概述
簡單介紹一下七大設計原則:
- 開閉原則:是所有面向對象設計的核心,對擴展開放,對修改關閉
- 依賴倒置原則:針對接口編程,依賴於抽象而不依賴於具體
- 單一職責原則:一個接口只負責一件事情,只能有一個原因導致類變化
- 接口隔離原則:使用多個專門的接口,而不是使用一個總接口
- 迪米特法則(最少知道原則):只和朋友交流(成員變量、方法輸入輸出參數),不和陌生人說話,控制好訪問修飾符
- 里氏替換原則:子類可以擴展父類的功能,但不能改變父類原有的功能
- 合成複用原則:儘量使用對象組合(has-a)/聚合(contanis-a),而不是繼承關係達到軟件複用的目的
合成複用原則
定義
合成複用原則(Composite/Aggregate Reuse Principle,CARP)是指儘量使用對象組 合(has-a)/聚合(contanis-a),而不是繼承關係達到軟件複用的目的。可以使系統更加靈 活,降低類與類之間的耦合度,一個類的變化對其他類造成的影響相對較少。
繼承我們叫做白箱複用,相當於把所有的實現細節暴露給子類。組合/聚合也稱之爲黑箱 複用,對類以外的對象是無法獲取到實現細節的。要根據具體的業務場景來做代碼設計, 其實也都需要遵循 OOP 模型。
示例
還是以數據庫操作爲例,先來創建 DBConnection
類:
/**
* @author eamon.zhang
* @date 2019-09-26 上午10:42
*/
public class DBConnection {
public String getConnection() {
return "MySQL 數據庫連接";
}
}
創建 ProductDao
類:
/**
* @author eamon.zhang
* @date 2019-09-26 上午10:43
*/
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
,來看代碼:
/**
* @author eamon.zhang
* @date 2019-09-26 上午10:42
*/
public abstract class DBConnection {
public abstract String getConnection();
}
然後,將 MySQL
的邏輯抽離:
/**
* @author eamon.zhang
* @date 2019-09-26 上午10:46
*/
public class MySQLConnection extends DBConnection {
@Override
public String getConnection() {
return "MySQL 數據庫連接";
}
}
再創建 Oracle
支持的邏輯:
/**
* @author eamon.zhang
* @date 2019-09-26 上午10:47
*/
public class OracleConnection extends DBConnection {
@Override
public String getConnection() {
return "Oracle 數據庫連接";
}
}
具體選擇交給應用層,來看一下類圖:
設計原則總結
學習設計原則,學習設計模式的基礎。在實際開發過程中,並不是一定要求所有代碼都 遵循設計原則,我們要考慮人力、時間、成本、質量,不是刻意追求完美,要在適當的 場景遵循設計原則,體現的是一種平衡取捨,幫助我們設計出更加優雅的代碼結構。