是否有可以处理方法调用依赖关系的设计模式?
Is there a design pattern that can deal with method call dependencies?
我的问题是这样的:
设计 c++ 类时,在某些情况下,某些方法只能在调用其他一些方法之后或在正确准备某些数据成员之后才能调用。
我发现当有一些数据成员依赖项通常不那么明显时,很难处理,并且需要扩展该类以支持更多特性和功能。这真的很容易出错。
在我的情况下,代码的执行速度并不重要,代码清晰度/可维护性/敏感性更重要。
如果method2
只能在method1
之后调用,那么类有一个状态。您希望保持状态一致,并且可能更改/使用此状态的方法不应损坏状态。
所以你需要封装。封装不是关于如何使字段成为私有并创建setField()
方法,而是关于谁可以改变状态。正确答案:只有对象可以改变其状态。如果每个字段都有 setter,则您有一个不受保护的对象,并且有关一致状态的控制权已泄露。
实际上,您可以重新设计代码,以便只能在前面的步骤中设置数据。在这种情况下,您不必担心每次调用时都检查"数据准备好了吗?"method2
。
为了避免不合时宜的呼叫,有几种方法。每个人都有赞成和反对。我想你有状态链0 ->方法1 ->状态1 ->方法2 ->状态2 ->方法3 ->状态3
-
如果对象具有不同的状态,则引发异常。 F.e. 在方法1中添加
if currentState.differs(state0) throw exception
最容易实现,这种方式不会帮助你理解和维护你的项目 -
使用状态和责任链模式的组合。将类分成几个,每个类都可以接受前一个作为输入参数,并返回链中的下一个类。F.e. 类 0 将具有带有签名的方法
Class1 method1(state0)
,类 1 具有Class2 method2(class1)
,类 2 具有state3 method3(class2)
。所以没有人可以调用Class2.method3
或method1(class3)
- 它不会编译。作为副作用,你会得到很多类。您也可以获得严格的工艺流程,但它可能比下一个选项更灵活。 - 使用模板模式。使用
process
方法创建一个Processor
类,并确保只有此类可以调用所需的方法。state3 process(state0) { prepareStuff(); state1 = method1(state0) somePreparation(state1) state2 = method2(state1) anotherPrepare(state2) return method3(state2) }
然后,您可以通过子类化Processor
和覆盖制备方法来更改流程。没有人可以推翻process()
.缺点是你总是得到整个过程,并且在方法2之后无法停止(事实上你可以,但它会导致状态泄漏,你再次得到无法控制的过程( 另请注意策略模板
从某种意义上说,这两种方式都在更高的层次上封装了过程状态。
还有另一种方法可以实现调用依赖关系。无论你选择什么,你都必须严格限制在任何地方随机调用方法的可能性。
您可以考虑添加一个枚举state
变量来记录对象的状态,并在需要按顺序调用的方法中处理状态检查和转换。 如果状态变得太复杂,你应该考虑修改你的类设计,也许把它分成更小的类。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 对在不同二进制文件中创建的对象文件的依赖关系
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- OpenVINO - 推理库插件 libMKLDNNPlugin.so 无法解析依赖关系
- 模拟测试中类的依赖关系
- C++模板方法中的循环依赖关系
- 解析正交模块的依赖关系
- 如何在 Mac OS 上安装 boost-mpi 及其对 clang 的依赖关系?
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 当依赖关系和依赖关系都是多态时,在哪个继承级别存储依赖关系指针?
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 为什么包含需要进一步的依赖关系?
- 使用 cmake 获取外部依赖关系
- CMake 外部和内部静态库的循环依赖关系
- 在没有Xcode的macOS中开发具有依赖关系的应用程序
- "std::shared_ptr"循环依赖关系是如何导致问题的