合成聚合原则

什么是合成聚合复用原则

  合成聚合复用原则是在一个新的对象里面使用一些已有的对象,是指成为新对象的一部分。新的对象通过想这些对象的委派达到复用已有功能的目的。

  简言之:尽量使用合成聚合,少用继承。

合成和聚合的区别

  合成(composition)和聚合(aggregation)都是关联的特殊种类。用C语言讲,合成是值的聚合,聚合则是引用的聚合。

  (1)聚合用来表示“拥有”关系或者整体与部分的关系。代表部分的对象有可能被多个代表整体的对象所共享,而且不一定随着某个代表整体的对象被销毁或破坏而被销毁破坏,部分的生命周期可以超越整体。例如,班级和学生,当班级删除后,学生还能存在。

1 public class Student {
2 
3 }
4 class Class{
5     private Student student;
6     public Class(Student student) {
7         this.student=student;
8     }
9 }

  (2)合成用来表示一种强得多“拥有关系”。在一个合成关系里,部分和整体的生命周期是一样的。一个合成的新对象完全拥有对其组成部分的支配权,包括它们的创建和湮灭等。使用程序语言的术语来说,合成而成的新对象对组成部分的内存分配、内存释放有绝对的责任。

例如,一个人由头、四肢和各种器官组成,人与这些具有相同的生命周期,人死了,这些器官也就挂了。房子和房间的关系,当房子没了,房间也不可能独立存在。

 1 public class House{
 2     private Room room;
 3     public House() {
 4         room= new Room();
 5     }
 6     public void createHouse(){
 7         room.createRoom();
 8     }
 9  }
10 
11 class Room{
12   public Room createRoom(){
13       System.out.println("创建房间");
14           return new Room();
15  }
16 }

  为什么使用合成聚合复用而不适用继承复用

 在面向对象的设计里,有两种基本的方法可以在不同的环境中复用已有的设计和实现,即通过合成/聚合复用和通过继承复用。两者的特点和区别,优点和缺点如下。

  1.合成聚合复用

  • 新对象存取对象的唯一方法是通过成分对象的接口。
  • 这种复用所需的依赖较少。
  • 这种复用可以再运行时间内动态进行,新对象可以动态地引用与成分对象类型相同的对象。

  一般而言,如果一个角色得到了更多的责任,那么可以使用合成/聚合关系将新的责任委派到合适的对象。当然,这种复用也有缺点。最主要的缺点就是通过这种复用建造的系统会有较多的对象需要管理。

  2.继承复用

  继承复用通过扩展一个已有对象的实现来得到新的功能,基类明显的捕获共同的属性和方法,而子类通过增加新的属性和方法来扩展超类的实现。继承是类型的复用。

  继承复用的优点

  • 新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。
  • 修改或扩展继承而来的实现较为容易。

  继承复用的缺点

  • 继承复用破坏包装,因为继承将超类的实现细节暴露给了子类。
  • 如果超类的实现改变了,那么子类的实现也不得不发生改变。因此,当一个基类发生了改变时,这种改变会传导到一级又一级的子类,使得设计师不得不相应的改变这些子类,以适应超类的变化。
  • 从超类继承而来的实现是静态的,不可能在运行时间内发生变化,因此没有足够的灵活性。

  由于继承复用有以上的缺点,所有尽量使用合成/聚合而不是继承来达到对实现的复用,是非常重要的设计原则。

posted @ 2020-03-21 21:10  崔小磊  阅读(191)  评论(0)    收藏  举报