我的问题是这样的:
在设计c ++类时,在某些情况下,某些方法只能在调用其他方法之后调用,或者在正确准备某些数据成员之后调用。
当发现某些数据成员依赖关系通常不那么明显时,我发现很难处理,并且需要扩展该类以支持更多功能和特性。它确实容易出错。
在我的情况下,代码的执行速度并不重要,代码清晰度/可维护性/敏感性更重要。
答案 0 :(得分:1)
如果只能在method2
之后调用method1
,则类具有状态。您希望保持状态一致,并且可以更改/使用此状态的方法不应该损坏状态。
所以你需要封装。封装不是关于如何将字段设为私有并创建setField()
方法,而是关于谁可以更改状态。正确答案:只有对象才能改变其状态。如果你有每个字段的setter你有一个不受保护的对象,并且已经泄漏了关于一致状态的控制。
实际上,您可以重新设计代码,以便仅在之前的步骤中设置数据。在这种情况下,您不必担心检查“数据准备好了吗?”每次method2
调用。
为了避免不合时宜的呼叫,有几种方法。每个人都有专业和反对。我想你有状态链0 - > method1 - > state1 - > method2 - > state2 - > method3 - > STATE3
如果对象具有不同的状态,则抛出异常。 F.E.在method1里面添加
if currentState.differs(state0) throw exception
最容易实现,这种方式对理解和维护项目没有帮助
使用State和Chain-of-responsibility模式的组合。将类分成几个,每个都可以接受前一个作为输入参数并返回链中的下一个类。 F.E. Class0将具有签名Class1 method1(state0)
的方法,Class1具有Class2 method2(class1)
而Class 2具有state3 method3(class2)
。所以没人能打电话给Class2.method3
或method1(class3)
- 它不会编译。作为一个副作用,你会得到很多课程。此外,您可以获得严格的流程,但它可能比下一个选项更灵活。
Processor
方法创建process
类,并确保只有此类可以调用所需的方法。
state3 process(state0) {
prepareStuff();
state1 = method1(state0)
somePreparation(state1)
state2 = method2(state1)
anotherPrepare(state2)
return method3(state2)
}
然后,您可以通过继承Processor
和重写准备方法来更改流程。没有人可以覆盖process()
。缺点是你总是得到整个过程并且不能在方法2之后停止(实际上你可以但它会导致泄漏状态并且你再次获得无法控制的过程)
另请注意policy模板从某种意义上讲,两种方式都可以将进程状态包含在更高的层次中。
还有另一种实现调用依赖的方法。无论你选择什么,你都必须严格限制随机调用方法的可能性。
答案 1 :(得分:0)
您可以考虑添加一个枚举state
变量来记录对象的状态,并处理需要按顺序调用的方法中的状态检查和转换。
如果状态变得太复杂,你应该考虑修改你的类设计,或者把它分成更小的类。