1. 程式人生 > >深入理解架構中的七大設計原則

深入理解架構中的七大設計原則

在進行軟體架構設計的工作時,需要遵循面向物件的設計原則。這些原則同樣體現在設計模式和架構模式之中,這些原則不斷的被淘汰,也有新的原則加入,正真流傳下來的並不多,本文中主要給大家介紹前人總結出來的七種設計原則。他們分別是:單一職責原則、里氏替換原則、開閉原則、依賴注入原則、介面分離原則、迪米特原則、合成複用原則。
在上一篇部落格上為大家介紹了單一職責原則,即系統裡的一個類應該只有一個單獨的職責。相信大家一定體會到了這樣做的好處吧,那麼這次咱們來聊聊其他設計原則。
先來聊聊里氏替換原則吧,來看下面這段程式碼:

public class Father {
    public Collection run
(HashMap map) { System.out.println("Father run....."); return map.values(); } }
public class Son extends Father{
    public Collection run(Map map) {
        System.out.println("Son run.....");
        return map.values();
    }
}
public class Test {
    public static void main
(String[] args) { /** * 此處的父類物件和子類物件的效果是一樣的 */ // Father f = new Father(); Son s = new Son(); HashMap map = new HashMap(); // f.run(map); s.run(map); } }

看上面的程式碼,Son類繼承自Father類,**並且過載了父類種的run方法,注意v這裡並不是重寫!**Father類種的run方法的引數是HashMap型別,但是Son中的run方法的引數是Map型別的。為什麼可以這樣呢????其實不難發現,在一個繼承體系中子類的功能應該是父類功能的擴充套件,而在這裡HashMap是Map的子類!!!
接著看test類中的測試程式碼,你和執行後就會發現s物件和f物件的效果是相同的!!!很神奇吧,其實這就是我接下來要給大家介紹的里氏替換原則,
所謂里氏替換原則的核心思想就是在任何父類物件出現的地方都就可以用他的子類物件來代替,並且效果是相同的。
該原則關注的是怎樣良好的使用繼承,不濫用繼承,他是繼承使用的基石。簡單來說里氏替換原則就是為了良好的繼承定義了一個規範可以分為4層含義:
第一:子類必須完全實現父類的方法,
第二:子類應該有自己的特性,但是也不影響父類的功能
第三:覆蓋或者實現父類方法的時候,該方法接收的引數型別可以被放大,即上述程式碼中的描述,個人認為這一點最有意思,所以寫了示例程式碼
第四:覆蓋或者實現父類方法的時候,該方法接收的引數型別可以被縮小。和第三點相似
好了,接下來聊聊下一個原則,依賴注入原則。
所謂依賴注入,就是依賴抽象而不依賴於具體的實現。理解起來有點抽象。先來看看這段程式碼:

public interface Itingting {
    /**
     * 婷婷會做飯的方法,
     * 具體做的什麼菜以抽象的方式宣告
     * 吃的時候進行例項化即可
     * 這樣做的好處就是一個方法可以宣告出婷婷會做好多菜
     * 想吃什麼菜就將那個菜進行例項化即可
     * @param food
     */
    public void cook(Food food);
}
public class TingTing implements Itingting {
    //婷婷實現做飯的介面
    @Override
    public void cook(Food food) {
        // TODO Auto-generated method stub
        food.eat();
    }
}
/**
 * 
 * @author婷婷
 * 食物類介面
 * 定義了一個eat方法
 *
 */
public interface Food {
    public void eat();
}
/**
 * 
 * @author婷婷
 * 食物類介面
 * 定義了一個eat方法
 *
 */
public interface Food {
    public void eat();
}
//做白菜
public class Cabbage implements Food{
    @Override
    public void eat() {
        // TODO Auto-generated method stub
        System.out.println("婷婷做的白菜也不錯!!!");
    }

}
/**
 * @author 婷婷
 * 描述婷婷在家吃飯的場景
 */
public class Home {
    public static void main(String[] args) {
        //創建出婷婷物件
        Itingting tingting = new TingTing();
        //呼叫婷婷做魚
        Food fish = new Fish();
        //呼叫婷婷做白菜
        Food cabbage = new Cabbage();
        //做好了就開始吃
        tingting.cook(fish);
        tingting.cook(cabbage);
    }
}

上述程式碼就是一個符合依賴注入原則的Demo,結合上述程式碼來解釋不難發現,其實該原則有以下三點說明:
1、高層模組不應該依賴於底層模組,兩者多應該依賴於抽象,
2、抽象不應該依賴於細節,即具體實現類。
3、細節應該依賴於抽象。
聽起來起來有點亂,看上述的程式碼吧,上述程式碼中將婷婷做飯的方法用抽象的形式描述,即說明婷婷會做各種菜,而不是單純的只會做某一種菜,當你需要吃什麼菜的時候
你就可以實現該介面(抽象)即可。這樣做的話就可以實現各個類或者模組之間的相互獨立,彼此之間互不影響。實現了模組之間的鬆耦合。
依賴注入原則有如下的三種方式實現:
1、通過建構函式傳遞依賴物件
2、通過setter來傳遞依賴物件
3、通過介面宣告實現依賴物件
上述程式碼中就是通過通過介面宣告實現依賴物件。好了,再來聊聊下一個設計原則吧。
介面分離原則:該原則的核心思想就是不強迫客戶程式依賴他們不需要的方法。簡而言之就是一個介面不需要提供太多的行為,一個介面應該只提供一種對外實現的功能,避免造成介面汙染。
這個原則其實很好理解,我們都知道,實現一個介面的時候我們必須要實現該介面的所有的抽象方法,而該介面中如果出現了我們並不需要的方法時就會造成介面汙染。
而介面分離原則就很好的解決了該問題。
接著就是第五個原則了,迪米特原則:該原則主要核心思想就是一個物件應該對其他物件經可能少的瞭解,也就是說降低各物件之間的耦合。其是我們在瞭解了前面集中原則之後應該不難理解這個。說白了。該原則就是為了類之間的解耦,只有類和類之間的耦合性比較低的時候才能夠更好的進行復用。
接著來看開閉原則:開閉原則也是比較簡單,該原則的核心思想主要就是對一個類的改動是通過增加程式碼進行的,而不能改動原來的程式碼。即一個物件對擴充套件開放,對修改關閉。
聊到了這裡你們有沒有發現前面的5種設計原則其實就是為了實現開閉原則!!!
沒錯!其實前面的幾種原則就是為了實現對擴充套件開放,對修改關閉的終極目標!
好了,相信大家已經瞭解到了架構中的這幾大設計原則了吧
哦!對了。還有合成複用原則。其實這個原則主要也是為了降低類和類之間的關係,即優先使用組合而不是繼承。
好了,關於架構中的設計原則就先給大家介紹到這裡了。
後續的文章將運用這些設計原則給大家介紹Java web相關的知識。