00_7面向对象设计原则-合成复用原则


定义:指尽量使用对象组合或对象聚合的方式实现代码复用,而不是用继承关系达到复用代码的目的。合成复用原则可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较小。 继承,又被称为白箱复用,相当于把所有实现细节暴露给子类。组合/聚合又被称为黑箱复用。对类以外的对象是无法获取到实现细节的。我们要根据具体的业务场景来做代码设计。   来我们看一个案例,还是以数据库操作为例,首先创建DBConnection类:
package org.test.design.principle.carp;

public class DBConnection {
    public String getConnection(){
        return "MySQL数据库连接";
    }
}
创建ProductDao类:
package org.test.design.principle.carp;

public class ProductDao {
    private DBConnection dbConnection;

    public void setDbConnection(DBConnection dbConnection) {
        this.dbConnection = dbConnection;
    }
    public void addProduct() {
        String conn = dbConnection.getConnection();
        System.out.println("使用" + conn + "增加产品");
    }
}
这是一种非常典型的合成复用原则应用场景。但是,对于目前的设计来说,DBConnection还不是一种抽象,不便于系统扩展。目前的系统支持MySQL数据库连接,假设业务发生变化,数据库操作层要支持Oracle数据库。当然,我们可以在DBConnection中增加对Oracle数据库支持的方法,但是这违背了开闭原则。其实,可以不必须修改Dao的代码,将DBConnection修改为abstract,代码如下:
package org.test.design.principle.carp;

public abstract class DBConnectionV2 {
    public abstract String getConnection();
}
然后将MySQL的逻辑抽离
package org.test.design.principle.carp;

public class MySQLConnection extends DBConnectionV2{
    @Override
    public String getConnection() {
        return "MySQL数据库连接";
    }
}
再创建Oracle支持的逻辑
package org.test.design.principle.carp;

public class OracleConnection extends DBConnectionV2{
    @Override
    public String getConnection() {
        return "Oracle数据库连接";
    }
}

此篇完。