委派模式與策略模式記錄

djyzq1450發表於2020-10-07

委派模式和策略模式:

委派模式:基本作用就是負責任務的排程與分配,更注重結果,從程式碼上看很像靜態代理。A 找B 做事,B將任務分配給手下人C、D …等人做,其中A 和 C、D並不接觸,通過B來操作

場景案例:客戶和專案經歷談需求,專案經理把任務分配給手下團隊中的人員

優缺點:

優點:可以將任務細化分配,統一管理可以加快任務的執行效率。

缺點:在任務比較複雜的情況下可能需要進行多重委派,容易造成紊亂。

public interface IEmployee {

    void doSomethings(String command);
}
package com.example.designPattern.delegate;

/**
 * @date 
 */
public class EmployeeA implements IEmployee {
    @Override
    public void doSomethings(String command) {
        System.out.println("員工A,擅長寫程式碼:" + command);
    }
}

package com.example.designPattern.delegate;

/**
 * @date 
 */
public class EmployeeB implements IEmployee{
    @Override
    public void doSomethings(String command) {
        System.out.println("員工B,擅長架構分析" + command);
    }
}

package com.example.designPattern.delegate;

import java.util.HashMap;
import java.util.Map;

/**
 * 分配任務的人,是需要知道 被分派任務的人的主要作用
 * @date 
 */
public class Leader {

    private Map<String,IEmployee> register = new HashMap<>();
	// 註冊式單例
    public Leader(){
        register.put("寫程式碼",new EmployeeA());
        register.put("架構設計",new EmployeeB());
    }
    public void doThings(String command){
        register.get(command).doSomethings(command);
    }
}

public class Boss {
	// 
    public void command(String command,Leader leader){
        leader.doThings(command);
    }
}

public class DelegateTest {
    public static void main(String[] args) {
        new Boss().command("架構設計",new Leader());
    }
}

類圖結構
類圖結構

設計模式的六大原則

  1. 開閉原則(Open Close Principle)
    開閉原則就是說對擴充套件開放,對修改關閉。在程式需要進行擴充的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。所以一句話概括就是:為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。

  2. 里氏代換原則(Liskov Substitution Principle)
    里氏代換原則(Liskov Substitution Principle LSP)物件導向設計的基本原則之一。 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承複用的基石,只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為。里氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。

  3. 依賴倒轉原則(Dependence Inversion Principle)
    這個是開閉原則的基礎,具體內容:真對介面程式設計,依賴於抽象而不依賴於具體。

  4. 介面隔離原則(Interface Segregation Principle)
    這個原則的意思是:使用多個隔離的介面,比使用單個介面要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實設計模式就是一個軟體的設計思想,從大型軟體架構出發,為了升級和維護方便。所以上文中多次出現:降低依賴,降低耦合。

  5. 迪米特法則(最少知道原則)(Demeter Principle)
    為什麼叫最少知道原則,就是說:一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。

  6. 合成複用原則(Composite Reuse Principle)
    原則是儘量使用合成/聚合的方式,而不是使用繼承。

  7. 單一職責原則

    一個類只做它該做的事情,類的職責要分明。

    單一職責原則想表達的就是"高內聚",寫程式碼最終極的原則只有六個字"高內聚、低耦合"

策略模式:

優點

1、避免了多重條件if…else if…else語句,多重條件語句並不容易維護

2、策略模式提供了管理相關演算法簇的辦法,恰當使用繼承可以把公共程式碼移到父類,從而避免了程式碼重複

缺點

1、客戶端必須知道所有的策略類,並自行決定使用 哪一個策略,這意味著客戶端必須理解這些演算法的區別,以便選擇恰當的演算法

2、如果備選策略很多,物件的資料會很多

模擬場景:

某售賣處,釋出活動,通過釋出優惠券,或者支付寶返現,以及可能存在其他的優惠方案,開展活動

public interface IPromotionStrategy {

    void doPromotion();
}
//優惠策略一:支付寶返現
public class CashBackPromotion implements IPromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("開展現金返支付寶活動");
    }
}
//策略二:釋出優惠券
public class CouponPromotion implements IPromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("開展優惠券活動活動");
    }
}
// 策略三:沒有任何優惠
public class NoPromotion implements IPromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("此時沒有任何的優惠活動");
    }
}
import java.util.HashMap;
import java.util.Map;

/**
 * desc:一個建立優惠策略的工廠,使用了註冊式單例
 * 使用列舉作為 註冊的key值
 * @auther
 * @date 2020/10/7 
 */
public class PromotionFactory {

    private static Map<Enum<?>,IPromotionStrategy> PROMOTION_STRATEGY = new HashMap<>();

    static {
        PROMOTION_STRATEGY.put(ActivityName.CASH,new CashBackPromotion());
        PROMOTION_STRATEGY.put(ActivityName.COUPON,new CouponPromotion());
    }
    private PromotionFactory(){}

    private static NoPromotion noPromotion = new NoPromotion();
    public static IPromotionStrategy getPromotion(Enum<ActivityName> activityName){
        return PROMOTION_STRATEGY.get(activityName) == null ? new NoPromotion():PROMOTION_STRATEGY.get(activityName);
    }

    static enum  ActivityName {
        /**
         * 現金活動,無活動,優惠券活動
         */
        CASH,COUPON;
    }

}
public class PromotionTest {
    public static void main(String[] args) {
        PromotionFactory.getPromotion(PromotionFactory.ActivityName.CASH).doPromotion();
        PromotionFactory.getPromotion(PromotionFactory.ActivityName.COUPON).doPromotion();
    }
}

類圖

相關文章