合成聚合原则

定义

尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的

聚合是has-A 的关系,组合是Contains-A的关系

优点

可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化,对其他类造成的的影响相对较少。

 

缺点

通过这种方式建造的系统会有较多的对象需要管理,也就是说A对象里边可能还有B类也有可能再加个C类,继承复用的优点是新的扩展性容易实现,继承了父类那么父类的大部分功能都可以进入子类,修改和扩展相对容易些。

 

继承复用的缺点:首先会破坏包装,继承将父类的实现细节暴露给子类,这种复用称之为白箱复用,组合聚合这种复用我们称之为黑箱复用,黑箱复用看不见实现细节。子类使用了父类的现成方法,这个时候父类的实现发生了改变,那么子类的实现也不得不发生改变。这两种方式各有千秋还是得根据实际的业务模型进行判断

 

合成(组合)/聚合以及继承之间的关系

聚合has-A ,组合contains-A,继承is-A

实例(获取数据库连接)

数据库连接类

public class DBConnection {
public String getConnection(){
return "MYSQL的数据连接";
}
}

产品操作类,通过继承DBConnection获取数据库连接对象
public class ProductDao extends DBConnection {
public void addProduct(){
String conn = super.getConnection();
System.out.println("使用" + conn + "增加产品");
}
}


测试类
public class Test {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.addProduct();
}
}

输出:使用MYSQL的数据连接增加产品

UML

 

 

但是我们此时要增加一个oracle数据库,则需要修改DBConnection,这显然违背了开闭原则

public class DBConnection {
public String getConnection(){
return "MYSQL的数据连接";
}
public String getOracleConnection(){
return "Oracle的数据连接";
}
}

合成聚合原则来重构代码

将数据库连接改成抽象的
public abstract class DBConnection {
/* public String getConnection(){
return "MYSQL的数据连接";
}*/
abstract String getConnection();


}

创建MySQL数据库连接类
public class MySQLConnection extends DBConnection{
@Override
String getConnection() {
return "MYSQL的数据连接";
}
}


创建Oracle数据库连接类

public class OracleConnection extends DBConnection {
@Override
String getConnection() {
return "Oracle的数据连接";
}
}

改造产品操作类

public class ProductDao {
/**
* 组合的方式注入数据库连接
*/
DBConnection dbConnection;

/**
* 注入数据库连接,可以使用set方法也可以使用构造器
* @param dbConnection
*/
public void setDbConnection(DBConnection dbConnection) {
this.dbConnection = dbConnection;
}

public void addProduct(){
String conn = dbConnection.getConnection();
System.out.println("使用" + conn + "增加产品");
}
}


测试类

public class Test {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.setDbConnection(new MySQLConnection());
productDao.addProduct();
productDao.setDbConnection(new OracleConnection());
productDao.addProduct();
}
}

输出:

  使用MYSQL的数据连接增加产品
  使用Oracle的数据连接增加产品

 

UML

 

 

综上将继承关系通过合成聚合设计原则完成了改造

posted @ 2020-03-21 19:16  叫熊猫啊  阅读(180)  评论(0编辑  收藏  举报