由于Smalltalk不鼓励使用caseOf:,在没有类爆炸的情况下实现以下情况有哪些备选方案?
self condition1
ifTrue: [ self actionForCondition1 ]
ifFalse: [
self condition2
ifTrue: [ self actionForCondition2 ]
ifFalse: [
self condition3
ifTrue: [ self actionForCondition3 ]
ifFalse: [ .... ] ] ]
答案 0 :(得分:6)
取决于您的情况究竟如何?
如果你的条件是型式试验
anObject isKindOf: aClass
您可以在课程上调度,这意味着您在anObject
上调用了一个操作方法。
如果你的条件是平等测试
anObject = anotherObject
您可以使用包含对象作为键的字典,将操作用作块闭包。
作为最后一次重新播放,如果没有其他帮助,您可能需要重写建议的代码以避免不必要的嵌套:
self condition1
ifTrue: [ ^ self actionForCondition1 ].
self condition2
ifTrue: [ ^ self actionForCondition2 ].
self condition3
ifTrue: [ ^ self actionForCondition3 ].
...
答案 1 :(得分:4)
如果滚动到
附近http://www.desk.org:8080/CampSmalltalk/control%20flow
你会找到句子
“在Smalltalk中有四种表达案例陈述的方法。”
后面是示例链接。
该文本位于稍长的一系列页面中间,偶尔会引用假设的导师和学生参加Smalltalk课程以达到说明目的;你可以忽略这个问题)
答案 2 :(得分:2)
我认为,在你必须编写这段代码的那一刻,我会问自己,为什么我必须编写这么多条件才能继续我的算法中的一个步骤。也许现在是时候思考模型有什么问题? 特别是,如果您认为消息查找语义实际上是一个case语句:
selector = selector1 ifTrue: [ invoke method1 ]
ifFalse: [ selector= selector2 ifTrue: [ invoke method2 ]
ifFalse: [...] ]]].
所以你应该试着把它变成你的优势 - 使用VM的switch语句而不是自己编写。
通过应用一个简单的原则:不要问(object isSomething ifTrue:[self doSomething])但是告诉(object doSomething),你可以避免在代码中有很多分支。 当然,有时它不适用并且在很大程度上取决于具体情况,但我通常更喜欢有额外的消息调度,而不是代码中的另一个分支。
答案 3 :(得分:1)
你应该看看double dispatching。根据测试和操作的实现方式,您可以使用双重调度来获得巨大优势。
您希望得到如下所示的代码:
self conditionAction performAction。
或
self conditinAction performAction:actionArgs
方法#conditionAction必须为每个唯一条件返回一个对象的唯一实例(不使用case语句本身:)。
您不希望通过创建类来强制解决问题,只是为了避免“案例陈述”,但在现实世界中,您可能已经拥有了一些可以利用的独特类。