合成复用原则(Composite Reuse Principle)
基本介绍
- 原则是尽量使用合成 / 聚合的方式,而不是使用继承
案例
方式一
package com.lango.principle.composite;
/**
* @author Lango
* @version 1.0
*/
public class Composite {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.addProduct();
}
}
// 数据库连接类
class DBConnection {
public String getConnection(){
return "MySQL 数据库连接";
}
}
class ProductDao extends DBConnection{
public void addProduct() {
String connection = super.getConnection();
System.out.println("使用 " + connection + " 执行数据库操作");
}
// 问题引出:
// 1. 当有多个数据库连接类时,如何扩展?
}
问题引出:
- 当有多个数据库连接类时,如何扩展?
在该示例中 ProductDao 继承自 DBConnection 类的 getConnection( ) 方法只能返回MySQL数据库的连接。但是,随着业务扩展功能增加,新增了Oracle数据库。此时,原本的 ProductDao 就不能满足需求了。虽然,我们可在DBConnection中再新增一个方法用于获取 Oracle 数据库的连接,但是这样显然违反了开闭原则。
改进
package com.lango.principle.composite.improve;
/**
* @author Lango
* @version 1.0
*/
public class Composite {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
MySQLConnection mySQLConnection = new MySQLConnection();
productDao.setDbConnection(mySQLConnection);
productDao.addProduct();
OracleConnection oracleConnection = new OracleConnection();
productDao.setDbConnection(oracleConnection);
productDao.addProduct();
}
}
// 数据库连接类
abstract class DBConnection{
public abstract String getConnection();
}
// MySQL 数据库
class MySQLConnection extends DBConnection{
@Override
public String getConnection() {
return "使用 MySQL 数据库连接";
}
}
// Oracle 数据库
class OracleConnection extends DBConnection{
@Override
public String getConnection() {
return "使用 Oracle 数据库连接";
}
}
class ProductDao {
private DBConnection dbConnection;
public void setDbConnection(DBConnection dbConnection) {
this.dbConnection = dbConnection;
}
public void addProduct(){
System.out.println(dbConnection);
System.out.println("执行数据库操作");
}
}
合成 / 聚合复用原则优点
- 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
- 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。
- 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。