在契约式设计中,类不变量必须在两种情况下得到满足:创建对象后和调用例程后。是否有任何示例或条件,我也必须在调用例程之前进行评估?
问问题
156 次
1 回答
5
在功能调用之前可以违反类不变量。条件可能不同,我只介绍最明显的条件:
别名。一个对象引用了一个类不变量中涉及的其他对象,并且该其他对象被第三方修改:
class SWITCH -- Creation procedure is ommitted for brevity. feature toggle1, toggle2: TOGGLE -- Mutually exclusive toggles. ... invariant toggle1.is_on = not toggle2.is_on end
现在下面的代码违反了 class 的不变量
SWITCH
:switch.toggle1.turn_on -- Make `switch.toggle1.is_on = True` switch.toggle2.turn_on -- Make `switch.toggle2.is_on = True` switch.operate -- Class invariant is violated before this call
外部状态。对象与在类不变量中引用的外部数据耦合,并且可能会意外更改:
class TABLE_CELL feature item: DATA do Result := cache -- Attempt to use cached value. if not attached Result then -- Load data from the database (slow). Result := database.load_item (...) cache := Result end end feature {NONE} -- Storage cache: detachable DATA invariant consistent_cache: -- Cache contains up-to-date value. attached cache as value implies value ~ database.load_item (...) end
现在如果在应用程序外部修改数据库,缓存可能会变得不一致,并且在以下功能调用之前触发类不变违规:
data := table_cell.item -- Class invariant is violated before this call.
打回来。一个对象可以在无效状态下传递给另一个对象:
class HANDLER feature process (s: STRUCTURE) do ... -- Some code that sets `is_valid` to False. s.iterate_over_elements (Current) end process_element (e: ELEMENT) do ... end is_valid: BOOLEAN do ... end invariant is_valid end
由类
HADNLER
的特性执行的对的回调会导致不变量违规,因为它的状态不佳:iterate_over_elements
STRUCTURE
handler
handler.process_element (...) -- Class invariant is violated before the call.
可以说所有情况都是由于软件错误和缺陷造成的,但这正是类不变量的目的,以捕捉那些包括在功能调用之前发生违规的情况。
于 2011-06-15T09:19:47.677 回答