1. 程式人生 > >設計模式的六大原則

設計模式的六大原則

下層 註意 本質 face ... att 抽象類 耦合 tar

一、設計模式的概念及作用

  設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。

二、六大原則

 1.單一職責原則(Single Responsibility Principle,簡稱SRP)

  1) 概念:一個類只負責一項職責。

  2) 舉例說明:假設有一個接口,如下:

 1   // 用戶接口
 2   public interface IUser{
 3       //
連接數據庫方法 4    public Connection getConnection(); 5   // 查詢用戶 6   public User qryUser(User user); 7   // 增加用戶 8   public int addUser(User user); 9   }

  當操作數據庫的信息改變的時候,需要修改大量的代碼,所以,可以將操作數據庫的方法抽離出來,將上面的用戶接口改為:

 1     // 數據庫操作類
 2     public class DBUtil{
 3         // 連接數據庫方法
4 public static Connection getConnection(){....} 5 } 6 7 // 用戶接口 8 public interface IUser{ 9 // 查詢用戶 10 public User qryUser(User user); 11 // 增加用戶 12 public int addUser(User user); 13 } 14 15 // 用戶實現類 16 public class UserImpl{
17 Connection connection = null; 18 // 查詢用戶 19 public User qryUser(User user){ 20 connection = DBUtil.getConnection(); 21 .... 22 } 23 // 增加用戶 24 public int addUser(User user){ 25 connection = DBUtil.getConnection(); 26 .... 27 } 28 }

  即,用戶接口中只操作用戶的基本信息,不操作數據庫。若要需要使用數據庫操作,將數據庫操作抽離出來,降低代碼的耦合性。

  3) 優點:類的復雜度降低、可讀性提高、可維護性提高、擴展性提高、降低了變更引起的風險。

 2.裏氏替換原則(Liskov Substitution Principle,簡稱LSP)

  之所以叫裏氏替換原則1988年,是因為該原則是由麻省理工學院的一位姓裏的女士(Barbara Liskov)提出來的。

  1) 概念:所有引用父類的地方必須能 透明使用子類,反過來 不成立。

  2) 舉例說明:

   喜歡動物 = 喜歡狗,因為動物中 包含狗,等式是成立的。

   喜歡狗 != 喜歡動物。 

class Animal{}
class Dog extends Animal{}

  3) 優點:增強程序的健壯性,即使增加了子類,原有的子類還可以繼續運行。

 3.依賴倒置原則(Dependence Inversion Principle,簡稱DIP)

  1) 概念:依賴倒置原則的本質就是通過抽象(接口或抽象類)使個各類或模塊的實現彼此獨立,互不影響,實現模塊間的松耦合。

  2)舉例說明:假設有一個CD唱片,CD唱片的播放 需要 CD播放機,即:

 1     // CD
 2     class CDRom{
 3         public void play(){
 4             System.out.println("play CDRom");
 5         }
 6     }
 7     
 8     // CD播放機
 9     class Player{
10         public void start(CDRom cd){
11             System.out.println("CD playing ...");
12             cd.play();
13         }
14     }
15     
16     // 測試方法
17     public class Main{
18         public static void main(Stirng[] args){
19             Player player = new Player();
20             CDRom cd = new CDRom();
21             player.start(cd);
22         }
23     }

  隨著科技的發達,DVD出現了,這時候就需要DVD播放機了,如下:

 1     // DVD
 2     class DVDRom{
 3         public void play(){
 4             System.out.println("play DVDRom");
 5         }
 6     }
 7     
 8     // DVD播放器
 9     class Player{
10         public void start(CDRom cd){
11             System.out.println("DVD playing ...");
12             cd.play();
13         }
14     }

  又隨著科技的發達,MP3、MP4等問世,這時候我們又需要定義更多的類,這樣子會很繁瑣,所以,可以定義一個上層接口,讓下層的類去實現,將上面的代碼 改為 如下:

 1     // 媒體接口
 2     inteferce Media{        // cd,dvd,mp3,mp4.mp5...
 3         public void play();
 4     }
 5     
 6     // DVD,並實現媒體接口
 7     class DVDRom impl Media{
 8         public void play(){
 9             System.out.println("play DVDRom");
10         }
11     }
12     
13     // CD,並實現媒體接口
14     class CDRom impl Media{
15         public void play(){
16             System.out.println("play CDRom");
17         }
18     }
19     
20     // 通用播放機
21     class Player{
22         public void start(Media media){
23             System.out.println("playing ...");
24             media.play();
25         }
26     }
27     
28     // 測試方法
29     public class Main{
30         public static void main(Stirng[] args){
31             Player player = new Player();
32             media cd = new CDRom();
33             
34             media dvd = new DVDRom();
35             player.start(dvd);
36         }
37     }

  3) 優點:在小型項目中很難體現出來。但在大中型項目中可以減少需求變化引起的工作量,使並行開發更友好。

 4.接口隔離原則(Interface Segregation Principle,簡稱ISP)

  1.概念:類間的依賴關系應該建立在最小的接口上。

   可以理解為:建立單一接口,不要建立龐大臃腫的接口,盡量細化接口,接口中的方法盡量少。也就是說,我們要為各個類建立專用的接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調用。

   一句話概括:一個接口中不要什麽事情都去做,其實什麽事情都做不好。

  2.舉例說明:

 1     // 燈接口
 2     interface light{
 3         // 開燈方法
 4         on();
 5         // 關燈方法
 6         off();
 7         // 維修方法
 8         repare(); 
 9         // 開電視方法
10         turnOnTV();  
11     }

  上面的燈接口中,既有燈的方法,又有工作人員的接口,又有電視的接口,這樣 一個接口就會顯得很臃腫,很龐大。

  運用接口隔離原則之後,將接口細化,分散為多個接口,可以預防外來變更的擴散。如下:

 1     // 燈接口
 2     interface light{
 3         // 開燈方法
 4         on();
 5         // 關燈方法
 6         off();
 7     }
 8     
 9     // 電視接口
10     intefece tv{
11         // 開電視接口
12         on();
13         // 關電視接口
14         off();
15     }
16     
17     // 工作人員
18     intefece worker{
19         // 維修
20         repaire();
21     }

  3.優點:通過分散定義多個接口,可以預防外來變更的擴散,提高系統的靈活性和可維護性。

 5.迪米特法則(Law of Demeter,簡稱LoD)

  1.概念:類間解耦。

  2.問題由來:類與類之間的關系越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。

  3.註意點:迪米特法則的初衷是降低類之間的耦合,由於每個類都減少了不必要的依賴,因此的確可以降低耦合關系。但是凡事都有度,雖然可以避免與非直接的類通信,但是要通信,必然會通過一個“中介”來發生聯系。過分的使用迪米特原則,會產生大量這樣的中介和傳遞類,導致系統復雜度變大。所以在采用迪米特法則時要反復權衡,既做到結構清晰,又要高內聚低耦合。

 6.開閉原則(Open Close Principle,簡稱OCP)

  1). 思想:盡量通過擴展軟件實體來解決需求變化,而不是通過修改已有的代碼來完成變化。

  2). 開:對擴展開放

   關:對修改關閉

  總結:單一職責原則告訴我們實現類要職責單一;

     裏氏替換原則告訴我們不要破壞繼承體系;

     依賴倒置原則告訴我們要面向接口編程;

     接口隔離原則告訴我們在設計接口的時候要精簡單一;

  迪米特法則告訴我們要降低耦合;

     開閉原則是總綱,他告訴我們要對擴展開放,對修改關閉。  

設計模式的六大原則