面向对象的设计规则(1) - 将(对象)组合推荐而不是(类)继承
[青睐]
组合
1。(对象)组合是一种重用方法,它通过创建组合其他对象的对象来获得新功能。
2。将函数委托给组合对象以获得新功能。
3。有时也称为“汇总”()或“包含”(),尽管一些作者对这些术语给出了特殊含义。
4。例如:
一个。聚合:一个对象具有另一个对象或负责另一个对象(即,一个对象包含另一个对象或是另一个对象的一部分),而聚合对象及其所有者具有相同的生命周期。 (翻译说明:所谓的“相同的生与死”关系可以在GOF中找到
:of-介绍部分。 )
b。包容性:一种特殊的组合。对于其他对象,容器中包含的对象是看不见的,其他对象只能通过容器对象访问包含的对象。 (coad)
5。可以通过以下两种方式实施包含:
一个。通过参考(通过)
B.值
6.C ++允许根据值或引用来实现包含。
7。但是在Java中,一切都是对对象的引用!
组合的利弊
1。优势:
一个。容器类只能通过包含对象的接口访问它。
b。 “黑匣子”重复使用,因为包含对象的内部细节是外部看不见的。
c。适合。
d。实施中的相互依赖性相对较小。 (翻译说明:包含对象和容器对象之间的依赖性较少)
e。每个课程仅关注一个任务。
f。通过获取对同一类型的其他对象的引用,可以在运行时动态定义组合(对象)。
2。缺点:
一个。这导致系统中的对象太多。
B为了将多个不同的对象用作复合块,必须仔细定义接口。
继承
1。(类)继承是一种重用方法,它通过扩展现有对象的实现来获得新功能。
2。广义类(超类)可以明确捕获这些常见的属性和方法。
3。特殊类(子类)通过附加属性和方法扩展。
继承的优点和缺点
1。优势:
一个。新实施很容易实施,因为其中大多数都是可以遗传的。
b。易于修改或扩展这些重复使用的实现。
2。缺点:
一个。打破封装,因为这将父类的实现详细信息揭示到子类。
b。 “白盒”重用,因为子类通常可以看到父类的内部细节。
c。当实现父类改变时,子类不得相应更改。
d。从父类继承的实现将不会在运行时更改。
COAD规则
仅在满足以下所有标准时才能使用继承:
一个。子类表达“是...的特殊类型”,而不是“ ...扮演的角色”。
子类B的实例不需要将()转换为另一类的对象。
c。子类扩展其父级的职责(),而不是重写或废除()。
d。子类不扩展仅是工具类的功能。
e。对于位于实际问题域()中的类中的类,其子类专门指角色(角色),事务()或设备()。
继承/组合示例1
1。“这是一种特殊的...”,而不是“ ...扮演的角色
- >失败。乘客是人们扮演的角色。代理商也是如此。
2。无需转换
- >失败。随着时间的流逝,子类实例可能会从代理转换为代理。
3。扩展,不重写和废除
- >通过。
4。不要扩展工具类
- >通过。
5。在问题域中,它专门指角色,交易或设备
- >失败。不是角色,交易或设备。
继承在这里不适用!
使用组合保存!
继承/组合示例2
1。“这是一种特殊的...”,而不是“ ...扮演的角色
- >通过。乘客和代理商是特殊类型的人扮演的角色。
2。无需转换
- >通过。一个物体将保持不变;代理对象也是如此。
3。扩展,不重写和废除
- >通过。
4。不要扩展工具类
- >通过。
5。在问题域中,它专门指角色,交易或设备
- >通过。这是一种角色。
继承在这里适用!
继承/组合示例3
1。“这是一种特殊的...”,而不是“ ...扮演的角色
- >通过。预订和购买都是特殊类型的交易类型。
2。无需转换
- >通过。一个物体将保持不变;对象也会。
3。扩展,不重写和废除
- >通过。
4。不要扩展工具类
- >通过。
5。在问题域中,它专门指角色,交易或设备
- >通过。这是一项交易。
继承在这里适用!
继承/组合示例4
1。“这是一种特殊的...”,而不是“ ...扮演的角色
- >失败。预订不是一种特殊类型。
2。无需转换
- >@ 0.通过。一个物体将保持不变。
3。扩展,不重写和废除
- >通过。
4。不要扩展工具类
- >失败。这是工具类。
5。在问题域中,它专门指角色,交易或设备
- >不适用。它是工具类,而不是一类问题域。 。
继承在这里不适用!
继承/组合摘要
1。组合和继承是重要的重用方法
2。在OO开发的早期阶段,继承被过度使用
3。随着时间的流逝,我们发现优先使用组合可以实现更好的可重复性和简单性设计
4。当然,它可用于扩展可用组合类的集合()()。
5。因此,组合和继承可以共同起作用
6。但是我们的基本规则是:
使用对象组合而不是(类)继承