通过组合进行责任委托是一种编程实践,其中一个类的对象包含另一个(或多个)类的对象,并使用这些对象来实现其部分逻辑,而不是继承它们的接口。
早期的面向对象编程(OOP)强调继承,但随着时间的推移,实践表明,组合通常提供更大的灵活性、可扩展性和降低组件之间的耦合。
继承将对象紧密绑定:基类的更改会影响所有子类,层次结构变得复杂,架构变得脆弱。组合消除了这些问题,允许构建更可靠和可维护的系统。
在C++中,委托通过将一个类的对象作为另一个类的成员来实现。在包装类中调用嵌套对象的方法。
代码示例:
class Logger { public: void log(const std::string& msg) { std::cout << msg << std::endl; } }; class FileProcessor { Logger logger; // 组合 public: void process(const std::string& filename) { logger.log("Processing file: " + filename); // ... } };
关键特点:
组合能否完全替代继承?
不,继承用于需要“是”(is-a)关系的地方,而组合用于“拥有”(has-a)关系的地方。例如,Button继承自Widget,但Car“拥有”Engine(组合)。
在组合中可以改变委托方法的行为吗?
可以,委托的方法可以在不触及原始类的情况下进行适配。还可以动态改变委托对象(例如,通过指针或唯一指针)。
组合是否比继承慢?
不,在大多数情况下性能没有差异。有时继承会因为虚拟调用(vtable)而增加开销,而组合只增加对象的大小。
在项目中,所有对话框都继承了共同的DialogWindow。添加新的业务逻辑会导致所有继承者的代码失效。
优点:
缺点:
将公共功能提取到单独的类中(日志、验证),通过组合注入到每个对话框中。
优点:
缺点: