# 合成复用原则
合成(组合)/ 聚合复用原则
定义:尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的
- 聚合 has-A
- 组合 contains-A
- 继承 is-A
优点:可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少
# 何时使用合成/聚合、继承
聚合:大雁去群的例子;笔记本和 U 盘,笔记本没了,U 盘还能独立存在 组合:集成显卡和笔记本,显卡坏了,你电脑也不能用了,看不见,不能操作了
代码场景:a 类中有一个 b类的引用
- 聚合:除了 a 类以外,还有其他地方对 b 类的引用,就算 a 类结束了,b 还存活着
- 组合:只有 a 类引用,那么当 a 类结束时, b 类跟着一起结束
# Coding
场景:Dao 层获取数据库连接;
public class DBConnection {
public String getConnection() {
return "使用 Mysql 数据库连接";
}
}
public class ProductDao extends DBConnection {
public void addProduct() {
String connection = super.getConnection();
System.out.println("使用 " + connection + " 添加产品");
}
}
public class Test {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.addProduct();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
需求来了:增加了 Postgresql 数据库,要切换数据源怎么办?
在上面的示例中,可能的修改如下:
- 增加 PostgresqlConnection 修改 ProductDao的继承类
- 在 DBConnection 中新增获取 PostgresqlConnection 的方法
上面这样做,都破坏了开闭原则。下面使用合成/复用原则来改造
# 合成/复用 改造场景
public interface DBConnection {
String getConnection();
}
public class MysqlDBConnection implements DBConnection {
@Override
public String getConnection() {
return "使用 Mysql 数据库连接";
}
}
public class PostgreesqlDBConnection implements DBConnection {
@Override
public String getConnection() {
return "使用 Postgreesql 数据库连接";
}
}
public class ProductDao {
private DBConnection dbConnection;
public void addProduct() {
String connection = dbConnection.getConnection();
System.out.println("使用 " + connection + " 添加产品");
}
public void setDbConnection(DBConnection dbConnection) {
this.dbConnection = dbConnection;
}
}
public class Test {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.setDbConnection(new MysqlDBConnection());
// productDao.setDbConnection(new PostgreesqlDBConnection());
productDao.addProduct();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
组合,一对一,强依赖。符合开闭原则,也符合里氏替换原则。随意替换数据源