[b]合成/聚合复用原则[/b] 就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
另一个更简短的表述:要尽量使用合成/聚合,尽量不要使用继承。
[b]合成和聚合的区别[/b]
合成和聚合均是关联的特殊种类。聚合用来表示“拥有”关系或者整体与部分的关系;而合成则用来表示一种强得多的“拥有”关系。在一个合成关系里,部分和整体的生命周期是一样的。一个合成的新的对象完全拥有对其组成部分的支配权,包括它们的创建和销毁等。使用程序语言的术语来讲,组合而成的新对象对组成部分的内存分配、内存释放有绝对的责任。
[b]合成/聚合复用的好处:[/b]
1、新对象存取成分对象的唯一方法是通过成分对象的接口。
2、对这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。
3、这种复用支持包装。
4、这种复用所需的依赖较少。
5、每一个新的类可以将焦点集中在一个任务上。
6、这种复用可以在运行时间内动态进行,新对象可以动态地引用于成分对象类型相同的对象。
这个复用也是有缺点。[b]其中主要的缺点:[/b]是通过使用这种复用建造的系统会有较多的对象需要管理。
[b]继承复用的优点[/b]
利用继承关系达到复用的做法有下面的优点:
1、新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。
2、修改或扩展继承而来的实现较为容易。
[b]继承复用的缺点[/b]
1、继承复用破环包装,因为继承将超类的实现细节暴露给子类。由于超类的内部细节常常是对子类透明的,因此这种复用是透明的复用,又称‘白箱’复用。
2、如果超类的实现发生变化,那么子类的实现也不得不发生变化。因此当一个基类发生改变时,这种改变会先像水中投入石子引起来的水波一样,将变化一圈又一圈地传导到一级又一级的子类,使设计师不得不相应地改变这些子类,以适应超类的变化。
3、从超类继承而来的实现是静态的,不可能在运行时间内发生改变,因此没有足够的灵活性。
[img]http://dl.iteye.com/upload/attachment/434835/8bca32ce-cf1f-304a-ae7c-1f4aa684c2c3.png[/img]
[b]与里氏代换原则联合使用[/b]
里氏代换原则是继承复用的基石。如果在任何使用B类的地方都可以使用S类型,那么S类型才能称为B类型的子类型,而B类型才可以称为S类型的基类型。
[b]java语言API中的例子[/b]
在java语言API中,有几个明显违反这样原则的例子,其中最为著名的就是Stack和Properties。前者被不当地设置为Vector的子类。而Properties被不恰当地设置成Hashtable的子类。
Properties的对象p。p.getProperties(key)与p.get(key)会给出不同的结果。
另一个更简短的表述:要尽量使用合成/聚合,尽量不要使用继承。
[b]合成和聚合的区别[/b]
合成和聚合均是关联的特殊种类。聚合用来表示“拥有”关系或者整体与部分的关系;而合成则用来表示一种强得多的“拥有”关系。在一个合成关系里,部分和整体的生命周期是一样的。一个合成的新的对象完全拥有对其组成部分的支配权,包括它们的创建和销毁等。使用程序语言的术语来讲,组合而成的新对象对组成部分的内存分配、内存释放有绝对的责任。
[b]合成/聚合复用的好处:[/b]
1、新对象存取成分对象的唯一方法是通过成分对象的接口。
2、对这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。
3、这种复用支持包装。
4、这种复用所需的依赖较少。
5、每一个新的类可以将焦点集中在一个任务上。
6、这种复用可以在运行时间内动态进行,新对象可以动态地引用于成分对象类型相同的对象。
这个复用也是有缺点。[b]其中主要的缺点:[/b]是通过使用这种复用建造的系统会有较多的对象需要管理。
[b]继承复用的优点[/b]
利用继承关系达到复用的做法有下面的优点:
1、新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。
2、修改或扩展继承而来的实现较为容易。
[b]继承复用的缺点[/b]
1、继承复用破环包装,因为继承将超类的实现细节暴露给子类。由于超类的内部细节常常是对子类透明的,因此这种复用是透明的复用,又称‘白箱’复用。
2、如果超类的实现发生变化,那么子类的实现也不得不发生变化。因此当一个基类发生改变时,这种改变会先像水中投入石子引起来的水波一样,将变化一圈又一圈地传导到一级又一级的子类,使设计师不得不相应地改变这些子类,以适应超类的变化。
3、从超类继承而来的实现是静态的,不可能在运行时间内发生改变,因此没有足够的灵活性。
[img]http://dl.iteye.com/upload/attachment/434835/8bca32ce-cf1f-304a-ae7c-1f4aa684c2c3.png[/img]
[b]与里氏代换原则联合使用[/b]
里氏代换原则是继承复用的基石。如果在任何使用B类的地方都可以使用S类型,那么S类型才能称为B类型的子类型,而B类型才可以称为S类型的基类型。
[b]java语言API中的例子[/b]
在java语言API中,有几个明显违反这样原则的例子,其中最为著名的就是Stack和Properties。前者被不当地设置为Vector的子类。而Properties被不恰当地设置成Hashtable的子类。
Properties的对象p。p.getProperties(key)与p.get(key)会给出不同的结果。