合成聚合原则
定义
尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的
聚合是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
综上将继承关系通过合成聚合设计原则完成了改造