设计模式七大原则之合成复用原则
什么是合成复用原则
合成复用原则(Composite Reuse Principle), 尽量使用组合或者聚合的方式而不是继承达到软件复用的原则.
继承会增加对象间的耦合性, 继承称之为白箱复用
, 相当于把所有的实现细节暴露给子类. 组合/聚合称之为黑箱复用
, 对类以外的对象时无法获取到实现细节的.
合成复用原则的目的
- 减少对象间的依赖, 是系统更加灵活.
错误代码演示
类图
代码演示
package com.inconspicuousy.principle.crp.error;
/** 数据库连接对象 */
class DBConnection {
/** 获取到MySQl数据库连接 */
public String getDbConnection() {
return "MySQL 数据库连接";
}
}
/** 这里为了直接获取到数据库连接, 直接采用继承的方式 */
class ProductDao extends DBConnection{
public void addProduct() {
String dbConnection = getDbConnection();
System.out.println("使用" + dbConnection + "添加了一条数据");
}
}
/**
* 合成复用原则错误代码演示
*
* Composite Reuse Principle 合成复用原则
* @author peng.yi
*/
public class CrpErrorExample {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.addProduct();
}
}
运行结果
使用MySQL 数据库连接添加了一条数据
Process finished with exit code 0
分析
这里ProductDao
因为要获取到数据库连接而直接采用继承的方式, 虽然复用了代码, 但是增加了对象间的耦合性, 当我们需要扩展Oracle连接时, 这里针对ProductDao就需要修改逻辑. 既不符合开闭原则
,也不符合合成复用原则
.
优化逻辑
- 将
ProductDao
与DBConnection
类的依赖关系更换为组合的方式 - 将
DBConnection
设计为接口, 其实现类提供真实的连接, 方便扩展数据库连接.
优化后代码演示
类图
代码
package com.inconspicuousy.principle.crp.correct;
interface DBConnection {
String getConnection();
}
class MySqlDBConnection implements DBConnection{
@Override
public String getConnection() {
return "MySQL数据库连接";
}
}
class OracleDBConnection implements DBConnection {
@Override
public String getConnection() {
return "Oracle数据库连接";
}
}
class ProductDao {
// 采用组合的方式将 DBConnection 和 ProductDao 建立耦合关系
private DBConnection dbConnection;
public void setDbConnection(DBConnection dbConnection) {
this.dbConnection = dbConnection;
}
public void addProduct() {
String dbConnection = this.dbConnection.getConnection();
System.out.println("使用" + dbConnection + "添加了一条数据");
}
}
/**
* 合成复用原则正确示例
*
* @author peng.yi
*/
public class CrpCorrectExample {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.setDbConnection(new MySqlDBConnection());
productDao.addProduct();
productDao.setDbConnection(new OracleDBConnection());
productDao.addProduct();
}
}
运行结果
使用MySQL数据库连接添加了一条数据
使用Oracle数据库连接添加了一条数据Process finished with exit code 0
转载自:https://blog.csdn.net/qq844579582/article/details/109027500