国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
單一職責(zé)原則的定義(類、方法、接口)
開閉原則
里氏替換原則
依賴倒置(抽線細(xì)節(jié))
接口隔離原則(接口)
迪米特法則 (類與類之間的關(guān)系)
首頁(yè) Java Java基礎(chǔ) 設(shè)計(jì)模式的六大原則是什么

設(shè)計(jì)模式的六大原則是什么

Jan 06, 2023 pm 04:25 PM
設(shè)計(jì)模式

設(shè)計(jì)模式的六大原則:1、單一職責(zé)原則,其核心就是控制類的粒度大小、將對(duì)象解耦、提高其內(nèi)聚性;2、開閉原則,可以通過“抽象約束、封裝變化”來實(shí)現(xiàn);3、里氏替換原則,主要闡述了有關(guān)繼承的一些原則;4、依賴倒置原則,降低了客戶與實(shí)現(xiàn)模塊之間的耦合;5、接口隔離原則,是為了約束接口、降低類對(duì)接口的依賴性;6、迪米特法則,要求限制軟件實(shí)體之間通信的寬度和深度。

設(shè)計(jì)模式的六大原則是什么

本教程操作環(huán)境:windows7系統(tǒng)、java8版、DELL G3電腦。

對(duì)于設(shè)計(jì)模式,自己很早之前就看了好多本設(shè)計(jì)模式書籍,其中一些還看了好幾遍,也一直希望自己能在編碼的時(shí)候把這些設(shè)計(jì)模式用上去??墒牵谌粘5拇虼a中,用的做多的就是單例,其次是觀察者和建造者模式 ( builder ) 用得比較多,其他的基本很少用到。

用不到的原因是還是不能夠理解設(shè)計(jì)模式的思想,無法將這些設(shè)計(jì)模式和編碼遇到的問題聯(lián)系起來,從而用不到設(shè)計(jì)模式。

其實(shí)設(shè)計(jì)模式的提出都是為了解決一個(gè)常見的問題而總結(jié)出來的辦法。所以當(dāng)你思考采用何種設(shè)計(jì)模式的時(shí)候,你應(yīng)該先問問自己當(dāng)前問題的是什么?根據(jù)問題去選取合適的設(shè)計(jì)模式。

等你熟悉了設(shè)計(jì)模式的以后,你會(huì)發(fā)現(xiàn)部分設(shè)計(jì)模式之間存在包含關(guān)系,甚至很相像,但是不同的設(shè)計(jì)模式解決的問題是不一樣的。

當(dāng)我們?cè)谠O(shè)計(jì)一個(gè)模塊的時(shí)候可以從以下幾個(gè)角度去考慮:

  • 這個(gè)模塊與其他模塊的關(guān)系是什么樣的?

  • 模塊中哪些部分是不變的,哪些部分是在不斷變化的,是如何變化的?

  • 類與類之間的關(guān)系是怎么樣的,為什么需要依賴,怎么可以不依賴?

  • 要不要加一個(gè)接口?接口的存在是為了解決什么問題?

當(dāng)然,本文并不是教你是如何使用設(shè)計(jì)模式。而是講解設(shè)計(jì)模式的設(shè)計(jì)原則。設(shè)計(jì)模式在被設(shè)計(jì)出來的時(shí)候,也是遵循一些規(guī)則的。

設(shè)計(jì)模式六大原則,具體如下:

  • 單一職責(zé)原則(類和方法,接口)

  • 開閉原則 (擴(kuò)展開放,修改關(guān)閉)

  • 里氏替換原則(基類和子類之間的關(guān)系)

  • 依賴倒置原則(依賴抽象接口,而不是具體對(duì)象)

  • 接口隔離原則(接口按照功能細(xì)分)

  • 迪米特法則 (類與類之間的親疏關(guān)系)

每一個(gè)設(shè)計(jì)原則旁邊都有個(gè)括號(hào),是用來解釋,或者描述應(yīng)用范圍的。下面將詳細(xì)介紹每一個(gè)原則。

單一職責(zé)原則的定義(類、方法、接口)


單一職責(zé)原則(Single Responsibility Principle,SRP)又稱單一功能原則。這里的職責(zé)是指類變化的原因,單一職責(zé)原則規(guī)定一個(gè)類應(yīng)該有且僅有一個(gè)引起它變化的原因,否則類應(yīng)該被拆分(There should never be more than one reason for a class to change)。

該原則提出對(duì)象不應(yīng)該承擔(dān)太多職責(zé),如果一個(gè)對(duì)象承擔(dān)了太多的職責(zé),至少存在以下兩個(gè)缺點(diǎn):

  • 一個(gè)職責(zé)的變化可能會(huì)削弱或者抑制這個(gè)類實(shí)現(xiàn)其他職責(zé)的能力;

  • 當(dāng)客戶端需要該對(duì)象的某一個(gè)職責(zé)時(shí),不得不將其他不需要的職責(zé)全都包含進(jìn)來,從而造成冗余代碼或代碼的浪費(fèi)。

單一職責(zé)原則的優(yōu)點(diǎn)

單一職責(zé)原則的核心就是控制類的粒度大小、將對(duì)象解耦、提高其內(nèi)聚性。如果遵循單一職責(zé)原則將有以下優(yōu)點(diǎn)。

  • 降低類的復(fù)雜度。一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé),其邏輯肯定要比負(fù)責(zé)多項(xiàng)職責(zé)簡(jiǎn)單得多。

  • 提高類的可讀性。復(fù)雜性降低,自然其可讀性會(huì)提高。

  • 提高系統(tǒng)的可維護(hù)性??勺x性提高,那自然更容易維護(hù)了。

  • 變更引起的風(fēng)險(xiǎn)降低。變更是必然的,如果單一職責(zé)原則遵守得好,當(dāng)修改一個(gè)功能時(shí),可以顯著降低對(duì)其他功能的影響。

單一職責(zé)原則的實(shí)現(xiàn)方法

單一職責(zé)原則是最簡(jiǎn)單但又最難運(yùn)用的原則,需要設(shè)計(jì)人員發(fā)現(xiàn)類的不同職責(zé)并將其分離,再封裝到不同的類或模塊中。而發(fā)現(xiàn)類的多重職責(zé)需要設(shè)計(jì)人員具有較強(qiáng)的分析設(shè)計(jì)能力和相關(guān)重構(gòu)經(jīng)驗(yàn)。

示例

public interface UserService {
    
    public void login(String username, String password);
    public void register(String email, String username, String password);
    public void logError(String msg);
    public void sendEmail(String email);
    
}

這段代碼很顯然存在很大的問題,UserService 既要負(fù)責(zé)用戶的注冊(cè)和登錄,還要負(fù)責(zé)日志的記錄和郵件的發(fā)送,并且后者的行為明顯區(qū)別于前者。<br/>

假設(shè)我要修改發(fā)送郵件的邏輯就得修改這個(gè)類,這時(shí)候 qa 還得回歸登錄注冊(cè)邏輯,這樣明顯不合理。

因此我們需要進(jìn)行拆分,根據(jù)具體的職能可將其具體拆分如下:

UserService:只負(fù)責(zé)登錄注冊(cè)

public interface UserService {

    public void login(String username, String password);
    public void register(String email, String username, String password);

}

LogService :只負(fù)責(zé)日志<br/>

public interface LogService {
    public void logError(String msg);

}

EmailService: 只負(fù)責(zé)發(fā)送郵件

public interface EmailService {
    public void sendEmail(String email);

}

這時(shí)候,咱們?cè)偃セ仡櫱懊嫣岬降膬?yōu)點(diǎn),就能深深體會(huì)了。

這里只是講了接口,其實(shí)對(duì)類也一樣,甚至方法也是一樣的。

對(duì)于類來說,根據(jù)類名,確保里面提供的方法都是屬于這個(gè)類的。

對(duì)于方法,不要把不相關(guān)的對(duì)象實(shí)例作為參數(shù)傳進(jìn)來。如果你發(fā)現(xiàn)某個(gè)方法依賴某個(gè)不相關(guān)的對(duì)象,那么這個(gè)方法的實(shí)現(xiàn)可能就存在問題。

比如 android 中圖片下載后顯示到 imageView 中,我提供如下的方法:

loadImage(String url, ImageView view) {
// 下載圖片,展示圖片
}

對(duì)于 loadImage 這個(gè)方法,參數(shù) url 是ok 的,但是參數(shù) ImageView 卻是不合理的。因?yàn)檫@里做了兩個(gè)操作,下載圖片,展示圖片。應(yīng)該將這個(gè)方法在進(jìn)行拆分:

// 下載圖片 
loadImage(String url) {

}
// 顯示圖片
displayImage(String url, ImageView view) {

// 調(diào)用 getBitmap (url)  獲取圖片
// 獲取圖片后將其設(shè)置到 view 中。

}

// 根據(jù) url 獲取圖片, 
getBitmap(String url) {

}

這樣整個(gè)邏輯就很清晰。后續(xù)需要修改下載邏輯,也不會(huì)影響到展示邏輯。當(dāng)然其實(shí)還有個(gè)問題是,這兩個(gè)方法要不要放在一個(gè)類里面?

開閉原則


開閉原則的實(shí)現(xiàn)方法:可以通過“抽象約束、封裝變化”來實(shí)現(xiàn)開閉原則,即通過接口或者抽象類為軟件實(shí)體定義一個(gè)相對(duì)穩(wěn)定的抽象層,而將相同的可變因素封裝在相同的具體實(shí)現(xiàn)類中。

因?yàn)槌橄箪`活性好,適應(yīng)性廣,只要抽象的合理,可以基本保持軟件架構(gòu)的穩(wěn)定。而軟件中易變的細(xì)節(jié)可以從抽象派生來的實(shí)現(xiàn)類來進(jìn)行擴(kuò)展,當(dāng)軟件需要發(fā)生變化時(shí),只需要根據(jù)需求重新派生一個(gè)實(shí)現(xiàn)類來擴(kuò)展就可以了。

示例

// 矩形
public class Rectangle {

    public double getWidth() {
        return width;
    }
    
    public double getHeight() {
        return height;
    }

}

需要計(jì)算矩形的面積

// 面積計(jì)算器
public class AreaCalculator {

    public double area(Rectangle shape){
        return shape.getWidth() * shape.getHeight();
    }
}

假設(shè)這時(shí)候,又多了一個(gè)圓形類

// 圓形
public class Circular {

    public double getRadius(){
        return radius;
    }
}

同樣也需要計(jì)算他的面積,這時(shí)候就會(huì)變成下面這樣子:

public class AreaCalculator {

    public double area(Object shape){
        if(shape instanceof Rectangle) {
            Rectangle rectangle = (Rectangle) shape;
            return rectangle.getWidth() * rectangle.getHeight();
        } else if (shape instanceof Circular) {
            Circular circular = (Circular) shape;
            return circular.getRadius() * circular.getRadius() * Math.PI;
        } else {
            throw new RuntimeException("There is no such type.");
        }
    }
}

這么更改完成,完全沒有問題。但是在真實(shí)的生產(chǎn)環(huán)境中,情況更為復(fù)雜,更改涉及的部分較多,那樣就可能導(dǎo)致牽一發(fā)動(dòng)全身。并且,以前編寫的經(jīng)過測(cè)試的一些功能需要重新測(cè)試,甚至導(dǎo)致某些功能不可用。

改進(jìn)版,把計(jì)算面積這個(gè)公有邏輯變成一個(gè)接口:

public interface Shape {

    public double getArea();

}
 
public class Rectangle implements Shape{

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    public double getArea() {
        return getWidth() * getHeight();
    }
    
}

這樣,當(dāng)需求變更,需要計(jì)算圓形面積的時(shí)候,我們只需創(chuàng)建一個(gè)圓形的類,并實(shí)現(xiàn) Shape 接口即可:<br/>

public class Circular implements Shape {

    public double getRadius(){
        return radius;
    }

    public double getArea() {
        return getRadius() * getRadius() * Math.PI;
    }
}

計(jì)算三角形面積、四邊形面積... 的時(shí)候,我們只需讓它們?nèi)?shí)現(xiàn) Shape 接口即可,無需修改源代碼。

里氏替換原則


里氏替換原則主要闡述了有關(guān)繼承的一些原則,也就是什么時(shí)候應(yīng)該使用繼承,什么時(shí)候不應(yīng)該使用繼承,以及其中蘊(yùn)含的原理。里氏替換原是繼承復(fù)用的基礎(chǔ),它反映了基類與子類之間的關(guān)系,是對(duì)開閉原則的補(bǔ)充,是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。

里氏替換原則的作用

里氏替換原則的主要作用如下。

  • 里氏替換原則是實(shí)現(xiàn)開閉原則的重要方式之一。

  • 它克服了繼承中重寫父類造成的可復(fù)用性變差的缺點(diǎn)。

  • 它是動(dòng)作正確性的保證。即類的擴(kuò)展不會(huì)給已有的系統(tǒng)引入新的錯(cuò)誤,降低了代碼出錯(cuò)的可能性。

  • 加強(qiáng)程序的健壯性,同時(shí)變更時(shí)可以做到非常好的兼容性,提高程序的維護(hù)性、可擴(kuò)展性,降低需求變更時(shí)引入的風(fēng)險(xiǎn)。

里氏替換原則的實(shí)現(xiàn)方法(繼承)

里氏替換原則通俗來講就是:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。也就是說:子類繼承父類時(shí),除添加新的方法完成新增功能外,盡量不要重寫父類的方法。

根據(jù)上述理解,對(duì)里氏替換原則的定義可以總結(jié)如下:

  • 子類可以實(shí)現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法

  • 子類中可以增加自己特有的方法

  • 當(dāng)子類的方法重載父類的方法時(shí),方法的前置條件(即方法的輸入?yún)?shù))要比父類的方法更寬松

  • 當(dāng)子類的方法實(shí)現(xiàn)父類的方法時(shí)(重寫/重載或?qū)崿F(xiàn)抽象方法),方法的后置條件(即方法的的輸出/返回值)要比父類的方法更嚴(yán)格或相等

通過重寫父類的方法來完成新的功能寫起來雖然簡(jiǎn)單,但是整個(gè)繼承體系的可復(fù)用性會(huì)比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的概率會(huì)非常大。

如果程序違背了里氏替換原則,則繼承類的對(duì)象在基類出現(xiàn)的地方會(huì)出現(xiàn)運(yùn)行錯(cuò)誤。

這時(shí)其修正方法是:取消原來的繼承關(guān)系,重新設(shè)計(jì)它們之間的關(guān)系。

關(guān)于里氏替換原則的例子,最有名的是“正方形不是長(zhǎng)方形”。當(dāng)然,生活中也有很多類似的例子,例如,企鵝、鴕鳥和幾維鳥從生物學(xué)的角度來劃分,它們屬于鳥類;但從類的繼承關(guān)系來看,由于它們不能繼承“鳥”會(huì)飛的功能,所以它們不能定義成“鳥”的子類。同樣,由于“氣球魚”不會(huì)游泳,所以不能定義成“魚”的子類;“玩具炮”炸不了敵人,所以不能定義成“炮”的子類等。

對(duì)于正方形和長(zhǎng)方形最好的做法是再添加一個(gè)父類,他們同時(shí)繼承自這個(gè)父類。

依賴倒置(抽線細(xì)節(jié))


依賴倒置原則是實(shí)現(xiàn)開閉原則的重要途徑之一,它降低了客戶與實(shí)現(xiàn)模塊之間的耦合。

由于在軟件設(shè)計(jì)中,細(xì)節(jié)具有多變性,而抽象層則相對(duì)穩(wěn)定,因此以抽象為基礎(chǔ)搭建起來的架構(gòu)要比以細(xì)節(jié)為基礎(chǔ)搭建起來的架構(gòu)要穩(wěn)定得多。這里的抽象指的是接口或者抽象類,而細(xì)節(jié)是指具體的實(shí)現(xiàn)類。

使用接口或者抽象類的目的是制定好規(guī)范和契約,而不去涉及任何具體的操作,把展現(xiàn)細(xì)節(jié)的任務(wù)交給它們的實(shí)現(xiàn)類去完成。

依賴、倒置原則的作用

依賴倒置原則的主要作用如下。

  • 依賴倒置原則可以降低類間的耦合性。

  • 依賴倒置原則可以提高系統(tǒng)的穩(wěn)定性。

  • 依賴倒置原則可以減少并行開發(fā)引起的風(fēng)險(xiǎn)。

  • 依賴倒置原則可以提高代碼的可讀性和可維護(hù)性。

依賴倒置原則的實(shí)現(xiàn)方法

依賴倒置原則的目的是通過要面向接口的編程來降低類間的耦合性,所以我們?cè)趯?shí)際編程中只要遵循以下4點(diǎn),就能在項(xiàng)目中滿足這個(gè)規(guī)則。

  • 每個(gè)類盡量提供接口或抽象類,或者兩者都具備。

  • 變量的聲明類型盡量是接口或者是抽象類。

  • 任何類都不應(yīng)該從具體類派生。

  • 使用繼承時(shí)盡量遵循里氏替換原則。

依賴倒置原則在“顧客購(gòu)物程序”中的應(yīng)用。

分析:本程序反映了 “顧客類”與“商店類”的關(guān)系。商店類中有 sell() 方法,顧客類通過該方法購(gòu)物以下代碼定義了顧客類通過韶關(guān)網(wǎng)店 ShaoguanShop 購(gòu)物

class Customer {
    public void shopping(ShaoguanShop shop) {
        //購(gòu)物
        System.out.println(shop.sell());
    }
}

但是,這種設(shè)計(jì)存在缺點(diǎn),如果該顧客想從另外一家商店(如婺源網(wǎng)店 WuyuanShop)購(gòu)物,就要將該顧客的代碼修改如下:

class Customer {
    public void shopping(WuyuanShop shop) {
        //購(gòu)物
        System.out.println(shop.sell());
    }
}

顧客每更換一家商店,都要修改一次代碼,這明顯違背了開閉原則。

存在以上缺點(diǎn)的原因是:顧客類設(shè)計(jì)時(shí)同具體的商店類綁定了,這違背了依賴倒置原則。

解決方法是:定義“婺源網(wǎng)店”和“韶關(guān)網(wǎng)店”的共同接口 Shop,顧客類面向該接口編程,其代碼修改如下:

class Customer {
    public void shopping(Shop shop) {
        //購(gòu)物
        System.out.println(shop.sell());
    }
}

class Customer {
    public void shopping(Shop shop) {
        //購(gòu)物
        System.out.println(shop.sell());
    }
}

這樣,不管顧客類 Customer 訪問什么商店,或者增加新的商店,都不需要修改原有代碼了,其類如下圖所示:


顧客購(gòu)物程序的類圖
程序代碼如下:

package principle;
public class DIPtest
{
    public static void main(String[] args)
    {
        Customer wang=new Customer();
        System.out.println("顧客購(gòu)買以下商品:"); 
        wang.shopping(new ShaoguanShop()); 
        wang.shopping(new WuyuanShop());
    }
}
//商店
interface Shop
{
    public String sell(); //賣
}
//韶關(guān)網(wǎng)店
class ShaoguanShop implements Shop
{
    public String sell()
    {
        return "韶關(guān)土特產(chǎn):香菇、木耳……"; 
    } 
}
//婺源網(wǎng)店
class WuyuanShop implements Shop
{
    public String sell()
    {
        return "婺源土特產(chǎn):綠茶、酒糟魚……"; 
    }
} 
//顧客
class Customer
{
    public void shopping(Shop shop)
    {
        //購(gòu)物
        System.out.println(shop.sell()); 
    }
}

程序的運(yùn)行結(jié)果如下:

顧客購(gòu)買以下商品:
韶關(guān)土特產(chǎn):香菇、木耳……
婺源土特產(chǎn):綠茶、酒糟魚……

接口隔離原則(接口)


接口隔離原則(Interface Segregation Principle,ISP)要求程序員盡量將臃腫龐大的接口拆分成更小的和更具體的接口,讓接口中只包含客戶感興趣的方法。

2002 年羅伯特·C.馬丁給“接口隔離原則”的定義是:客戶端不應(yīng)該被迫依賴于它不使用的方法(Clients should not be forced to depend on methods they do not use)。該原則還有另外一個(gè)定義:一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上(The dependency of one class to another one should depend on the smallest possible interface)。

以上兩個(gè)定義的含義是:要為各個(gè)類建立它們需要的專用接口,而不要試圖去建立一個(gè)很龐大的接口供所有依賴它的類去調(diào)用。

接口隔離原則和單一職責(zé)都是為了提高類的內(nèi)聚性、降低它們之間的耦合性,體現(xiàn)了封裝的思想,但兩者是不同的:

  • 單一職責(zé)原則注重的是職責(zé),而接口隔離原則注重的是對(duì)接口依賴的隔離。

  • 單一職責(zé)原則主要是約束類,它針對(duì)的是程序中的實(shí)現(xiàn)和細(xì)節(jié);接口隔離原則主要約束接口,主要針對(duì)抽象和程序整體框架的構(gòu)建。

接口隔離原則的優(yōu)點(diǎn)

接口隔離原則是為了約束接口、降低類對(duì)接口的依賴性,遵循接口隔離原則有以下 5 個(gè)優(yōu)點(diǎn)。

  • 將臃腫龐大的接口分解為多個(gè)粒度小的接口,可以預(yù)防外來變更的擴(kuò)散,提高系統(tǒng)的靈活性和可維護(hù)性。

  • 接口隔離提高了系統(tǒng)的內(nèi)聚性,減少了對(duì)外交互,降低了系統(tǒng)的耦合性。

  • 如果接口的粒度大小定義合理,能夠保證系統(tǒng)的穩(wěn)定性;但是,如果定義過小,則會(huì)造成接口數(shù)量過多,使設(shè)計(jì)復(fù)雜化;如果定義太大,靈活性降低,無法提供定制服務(wù),給整體項(xiàng)目帶來無法預(yù)料的風(fēng)險(xiǎn)。

  • 使用多個(gè)專門的接口還能夠體現(xiàn)對(duì)象的層次,因?yàn)榭梢酝ㄟ^接口的繼承,實(shí)現(xiàn)對(duì)總接口的定義。

  • 能減少項(xiàng)目工程中的代碼冗余。過大的大接口里面通常放置許多不用的方法,當(dāng)實(shí)現(xiàn)這個(gè)接口的時(shí)候,被迫設(shè)計(jì)冗余的代碼。

接口隔離原則的實(shí)現(xiàn)方法

在具體應(yīng)用接口隔離原則時(shí),應(yīng)該根據(jù)以下幾個(gè)規(guī)則來衡量。

  • 接口盡量小,但是要有限度。一個(gè)接口只服務(wù)于一個(gè)子模塊或業(yè)務(wù)邏輯。

  • 為依賴接口的類定制服務(wù)。只提供調(diào)用者需要的方法,屏蔽不需要的方法。

  • 了解環(huán)境,拒絕盲從。每個(gè)項(xiàng)目或產(chǎn)品都有選定的環(huán)境因素,環(huán)境不同,接口拆分的標(biāo)準(zhǔn)就不同深入了解業(yè)務(wù)邏輯。

  • 提高內(nèi)聚,減少對(duì)外交互。使接口用最少的方法去完成最多的事情。

對(duì)于接口隔離,大家還是可以參考單一職責(zé)提到的示例:

public interface UserService {
    
    public void login(String username, String password);
    public void register(String email, String username, String password);
    public void logError(String msg);
    public void sendEmail(String email);
    
}

這時(shí)候,應(yīng)該就能理解拆分的好處了。

迪米特法則 (類與類之間的關(guān)系)


迪米特法則(Law of Demeter,LoD)又叫作最少知識(shí)原則(Least Knowledge Principle,LKP),產(chǎn)生于 1987 年美國(guó)東北大學(xué)(Northeastern University)的一個(gè)名為迪米特(Demeter)的研究項(xiàng)目,由伊恩·荷蘭(Ian Holland)提出,被 UML 創(chuàng)始者之一的布奇(Booch)普及,后來又因?yàn)樵诮?jīng)典著作《程序員修煉之道》(The Pragmatic Programmer)提及而廣為人知。

迪米特法則的定義是:只與你的直接朋友交談,不跟“陌生人”說話(Talk only to your immediate friends and not to strangers)。其含義是:如果兩個(gè)軟件實(shí)體無須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。其目的是降低類之間的耦合度,提高模塊的相對(duì)獨(dú)立性。

迪米特法則中的“朋友”是指:當(dāng)前對(duì)象本身、當(dāng)前對(duì)象的成員對(duì)象、當(dāng)前對(duì)象所創(chuàng)建的對(duì)象、當(dāng)前對(duì)象的方法參數(shù)等,這些對(duì)象同當(dāng)前對(duì)象存在關(guān)聯(lián)、聚合或組合關(guān)系,可以直接訪問這些對(duì)象的方法。

迪米特法則的優(yōu)點(diǎn)

迪米特法則要求限制軟件實(shí)體之間通信的寬度和深度,正確使用迪米特法則將有以下兩個(gè)優(yōu)點(diǎn)。

  • 降低了類之間的耦合度,提高了模塊的相對(duì)獨(dú)立性。

  • 由于親合度降低,從而提高了類的可復(fù)用率和系統(tǒng)的擴(kuò)展性。

但是,過度使用迪米特法則會(huì)使系統(tǒng)產(chǎn)生大量的中介類,從而增加系統(tǒng)的復(fù)雜性,使模塊之間的通信效率降低。所以,在釆用迪米特法則時(shí)需要反復(fù)權(quán)衡,確保高內(nèi)聚和低耦合的同時(shí),保證系統(tǒng)的結(jié)構(gòu)清晰。

迪米特法則的實(shí)現(xiàn)方法

從迪米特法則的定義和特點(diǎn)可知,它強(qiáng)調(diào)以下兩點(diǎn):

  • 從依賴者的角度來說,只依賴應(yīng)該依賴的對(duì)象。

  • 從被依賴者的角度說,只暴露應(yīng)該暴露的方法。

所以,在運(yùn)用迪米特法則時(shí)要注意以下 6 點(diǎn)。

  • 在類的劃分上,應(yīng)該創(chuàng)建弱耦合的類。類與類之間的耦合越弱,就越有利于實(shí)現(xiàn)可復(fù)用的目標(biāo)。

  • 在類的結(jié)構(gòu)設(shè)計(jì)上,盡量降低類成員的訪問權(quán)限。

  • 在類的設(shè)計(jì)上,優(yōu)先考慮將一個(gè)類設(shè)置成不變類。

  • 在對(duì)其他類的引用上,將引用其他對(duì)象的次數(shù)降到最低。

  • 不暴露類的屬性成員,而應(yīng)該提供相應(yīng)的訪問器(set 和 get 方法)。

  • 謹(jǐn)慎使用序列化(Serializable)功能

明星與經(jīng)紀(jì)人的關(guān)系實(shí)例。

分析:明星由于全身心投入藝術(shù),所以許多日常事務(wù)由經(jīng)紀(jì)人負(fù)責(zé)處理,如與粉絲的見面會(huì),與媒體公司的業(yè)務(wù)洽淡等。這里的經(jīng)紀(jì)人是明星的朋友,而粉絲和媒體公司是陌生人,所以適合使用迪米特法則,其類圖如下圖所示。


明星與經(jīng)紀(jì)人的關(guān)系圖
代碼如下:

package principle;
public class LoDtest
{
    public static void main(String[] args)
    {
        Agent agent=new Agent();
        agent.setStar(new Star("林心如"));
        agent.setFans(new Fans("粉絲韓丞"));
        agent.setCompany(new Company("中國(guó)傳媒有限公司"));
        agent.meeting();
        agent.business();
    }
}
//經(jīng)紀(jì)人
class Agent
{
    private Star myStar;
    private Fans myFans;
    private Company myCompany;
    public void setStar(Star myStar)
    {
        this.myStar=myStar;
    }
    public void setFans(Fans myFans)
    {
        this.myFans=myFans;
    }
    public void setCompany(Company myCompany)
    {
        this.myCompany=myCompany;
    }
    public void meeting()
    {
        System.out.println(myFans.getName()+"與明星"+myStar.getName()+"見面了。");
    }
    public void business()
    {
        System.out.println(myCompany.getName()+"與明星"+myStar.getName()+"洽淡業(yè)務(wù)。");
    }
}
//明星
class Star
{
    private String name;
    Star(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
}
//粉絲
class Fans
{
    private String name;
    Fans(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
}
//媒體公司
class Company
{
    private String name;
    Company(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
}

程序的運(yùn)行結(jié)果如下:

粉絲韓丞與明星林心如見面了。
中國(guó)傳媒有限公司與明星林心如洽淡業(yè)務(wù)。

?到此,設(shè)計(jì)模式的六大原則就講完了。

更多編程相關(guān)知識(shí),請(qǐng)?jiān)L問:編程教學(xué)?。?/p>

以上是設(shè)計(jì)模式的六大原則是什么的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1600
29
PHP教程
1502
276
Java框架中設(shè)計(jì)模式與架構(gòu)模式的區(qū)別 Java框架中設(shè)計(jì)模式與架構(gòu)模式的區(qū)別 Jun 02, 2024 pm 12:59 PM

在Java框架中,設(shè)計(jì)模式和架構(gòu)模式的區(qū)別在于:設(shè)計(jì)模式定義了在軟件設(shè)計(jì)中解決常見問題的抽象解決方案,關(guān)注類和對(duì)象之間的交互,如工廠模式。架構(gòu)模式定義了系統(tǒng)結(jié)構(gòu)和模塊之間的關(guān)系,關(guān)注系統(tǒng)組件的組織和交互,如分層架構(gòu)。

PHP設(shè)計(jì)模式:測(cè)試驅(qū)動(dòng)開發(fā)實(shí)踐 PHP設(shè)計(jì)模式:測(cè)試驅(qū)動(dòng)開發(fā)實(shí)踐 Jun 03, 2024 pm 02:14 PM

TDD用于編寫高質(zhì)量PHP代碼,步驟包括:編寫測(cè)試用例,描述預(yù)期功能并使其失敗。編寫代碼,僅使測(cè)試用例通過,無需過分優(yōu)化或詳細(xì)設(shè)計(jì)。測(cè)試用例通過后,優(yōu)化和重構(gòu)代碼以提高可讀性、可維護(hù)性和可擴(kuò)展性。

Guice框架中設(shè)計(jì)模式的應(yīng)用 Guice框架中設(shè)計(jì)模式的應(yīng)用 Jun 02, 2024 pm 10:49 PM

Guice框架應(yīng)用了多項(xiàng)設(shè)計(jì)模式,包括:?jiǎn)卫J剑和ㄟ^@Singleton注解確保類只有一個(gè)實(shí)例。工廠方法模式:通過@Provides注解創(chuàng)建工廠方法,在依賴注入時(shí)獲取對(duì)象實(shí)例。策略模式:將算法封裝成不同策略類,通過@Named注解指定具體策略。

Java設(shè)計(jì)模式之裝飾器模式剖析 Java設(shè)計(jì)模式之裝飾器模式剖析 May 09, 2024 pm 03:12 PM

裝飾器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,允許動(dòng)態(tài)添加對(duì)象功能,無需修改原始類。它通過抽象組件、具體組件、抽象裝飾器和具體裝飾器的協(xié)作實(shí)現(xiàn),可以靈活擴(kuò)展類功能,滿足變化的需求。示例中,將牛奶和摩卡裝飾器添加到Espresso,總價(jià)為2.29美元,展示了裝飾器模式在動(dòng)態(tài)修改對(duì)象行為方面的強(qiáng)大功能。

Spring MVC框架中設(shè)計(jì)模式的應(yīng)用 Spring MVC框架中設(shè)計(jì)模式的應(yīng)用 Jun 02, 2024 am 10:35 AM

SpringMVC框架使用以下設(shè)計(jì)模式:1.單例模式:管理Spring容器;2.門面模式:協(xié)調(diào)控制器、視圖和模型交互;3.策略模式:根據(jù)請(qǐng)求選擇請(qǐng)求處理程序;4.觀察者模式:發(fā)布和監(jiān)聽?wèi)?yīng)用程序事件。這些設(shè)計(jì)模式增強(qiáng)了SpringMVC的功能和靈活性,使開發(fā)者可以創(chuàng)建高效、可維護(hù)的應(yīng)用程序。

java框架中使用設(shè)計(jì)模式的優(yōu)缺點(diǎn)有哪些? java框架中使用設(shè)計(jì)模式的優(yōu)缺點(diǎn)有哪些? Jun 01, 2024 pm 02:13 PM

Java框架中使用設(shè)計(jì)模式的優(yōu)點(diǎn)包括:代碼可讀性、可維護(hù)性和可擴(kuò)展性增強(qiáng)。缺點(diǎn)包括:過度使用導(dǎo)致復(fù)雜性、性能開銷以及學(xué)習(xí)曲線陡峭。實(shí)戰(zhàn)案例:代理模式用于延遲加載對(duì)象。明智地使用設(shè)計(jì)模式可充分利用其優(yōu)勢(shì)并最小化缺點(diǎn)。

PHP設(shè)計(jì)模式:用于解決特定軟件問題的模式 PHP設(shè)計(jì)模式:用于解決特定軟件問題的模式 Jun 01, 2024 am 11:07 AM

PHP設(shè)計(jì)模式提供了已知解決方案來應(yīng)對(duì)軟件開發(fā)中常見的問題。常見的模式類型包括創(chuàng)建型(例如工廠方法模式)、結(jié)構(gòu)型(例如裝飾器模式)和行為型(例如觀察者模式)。設(shè)計(jì)模式在解決重復(fù)性問題、提高可維護(hù)性和促進(jìn)團(tuán)隊(duì)合作時(shí)特別有用。在電商系統(tǒng)中,觀察者模式可以實(shí)現(xiàn)購(gòu)物車與訂單狀態(tài)之間的自動(dòng)更新??傮w而言,PHP設(shè)計(jì)模式是創(chuàng)建健壯、可擴(kuò)展且可維護(hù)應(yīng)用程序的重要工具。

設(shè)計(jì)模式與測(cè)試驅(qū)動(dòng)開發(fā)的關(guān)系 設(shè)計(jì)模式與測(cè)試驅(qū)動(dòng)開發(fā)的關(guān)系 May 09, 2024 pm 04:03 PM

TDD與設(shè)計(jì)模式可提高代碼質(zhì)量和可維護(hù)性。TDD確保測(cè)試覆蓋率,提高可維護(hù)性,并提高代碼質(zhì)量。設(shè)計(jì)模式通過松耦合和高內(nèi)聚等原則協(xié)助TDD,確保測(cè)試覆蓋應(yīng)用程序行為的各個(gè)方面。它還通過可重用性,可維護(hù)性和更健壯的代碼提高可維護(hù)性和代碼質(zhì)量。

See all articles