本文来了解一下什么是组合聚合复用原则。
定义
- 尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的
- 优点:可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少
- 继承使白箱复用;组合聚合是黑箱复用。
- 聚合:has-A;组合:contains-A;继承:is-A
- 聚合:电脑和U盘,两者可以独立
- 组合:国和家,没有国就没有家
例子
首先一个场景,是获取数据库连接,定义一个获取连接的类:
1 2 3 4 5
| public class DBConnection { public String getConnection(){ return "mysql数据库连接。。。"; } }
|
下面我的产品需要获取这个数据库连接:
1 2 3 4 5 6
| public class ProductDao extends DBConnection{ public void addProduct(){ String conn = super.getConnection(); System.out.println("获取"+conn); } }
|
那如果我可能要在多个数据之间切换呢?直接改不符合开闭原则,显然这个代码需要重构,将其用组合聚合来重构,定义一个抽象类:
1 2 3
| public abstract class NewDBConnection { abstract String getConnection(); }
|
Mysql数据库连接:
1 2 3 4 5 6
| public class MysqlConnection extends NewDBConnection { @Override String getConnection() { return "Mysql数据库连接..."; } }
|
Oracle数据库连接:
1 2 3 4 5 6
| public class OracleConnection extends NewDBConnection { @Override String getConnection() { return "Oracle数据库连接..."; } }
|
产品获取数据库连接,这里是用了组合模式:
1 2 3 4 5 6 7 8 9 10 11 12
| public class NewProductDao extends DBConnection{ private NewDBConnection dbConnection;
public void setDbConnection(NewDBConnection dbConnection) { this.dbConnection = dbConnection; }
public void addProduct(){ String conn = dbConnection.getConnection(); System.out.println("获取"+conn); } }
|
那么,就可以在应用层进行切换了:
1 2 3 4 5 6 7
| public class Test { public static void main(String[] args) { NewProductDao productDao = new NewProductDao(); productDao.setDbConnection(new MysqlConnection()); productDao.addProduct(); } }
|