23種設計模式(一)-組件協做模式

典型的三種組件協做模式

Template Method:模板方法模式

在軟件構建過程當中,對於某項任務,經常有穩定的總體操做結構,可是各個子步驟卻有不少改變的需求,或者因爲固有的緣由沒法和任務總體結構同時實現。算法

定義一個算法的骨架,講一些步驟(變化的)延遲到子類中,是的子類能夠複用一個算法的結構(骨架)並從新定義(overwrite)某些特定的步驟設計模式

eg1:不使用Template Method
public class TemplateMethod {
    public boolean stap2() {
        return false;
    }

    public void stap4() {
    }

    public void run() {
        TemplateMethod templateMethod = new TemplateMethod();
        Lib lib = new Lib();
        try {
            lib.stap1();
            if (templateMethod.stap2()) {
                lib.stap3();
            } else {
                templateMethod.stap4();
            }
            lib.stap5();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Lib {
    public void stap1() {
    }

    public boolean stap3() {
        return false;
    }

    public void stap5() {
    }
}

弊端:TemplateMethod 要實現 run()、 stap2() 、stap4()方法,然而run()在此例中屬於比較穩定的模塊,屬於整個算法的骨架。屬於子類調用父類方法(早綁定)ide

eg2:使用Template Method
public class TemplateMethod2 extends Lib2 {

    @Override
    public boolean stap2() {//變化點
        return false;
    }

    @Override
    public void stap5() {//變化點
    }

    public static void main(String[] args) {
        Lib2 templateMethod2 = new TemplateMethod2();
        templateMethod2.run();
    }
}

abstract class Lib2 {
    public void stap1() {
    }

    public abstract boolean stap2();// 聲明爲抽象方法

    public boolean stap3() {
        return false;
    }

    public void stap4() {
    }

    public abstract void stap5(); // 聲明爲抽象方法

    public void run() {  //穩定骨架(模板)
        try {
            stap1();
            if (stap2()) {
                stap3();
            } else {
                stap4();
            }
            stap5();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

優勢:TemplateMethod2 要實現 stap2() 、stap4()方法,然而run()在此例中屬於比較穩定的模塊,屬於整個算法的骨架已經在父類中實現。屬於父類調用子類方法(晚綁定)。性能

模板方法模式類圖.png

Strategy:策略模式

在軟件構建過程當中,某些對象使用個算法可能多種多樣,常常改變,若是將這些算法都編碼到對象中,將會使得對象變得異常複雜;並且有時候支持不是用的算法也是一個性能負擔。測試

定義一系列算法,把它們一個個封裝起來,而且使它們能夠互相替換(變化)。該模式使得算法能夠獨立於使用它的客戶程序(穩定)而變化(擴展、子類化).this

//策略接口
public interface Strategy {
    //定義的抽象算法方法 來約束具體的算法實現方法
    public void algorithmMethod();
}

// 具體的策略實現1
class ConcreteStrategy1 implements Strategy {
    //具體的算法實現
    @Override
    public void algorithmMethod() {
        System.out.println("ConcreteStrategy1");
    }
}

// 具體的策略實現2
class ConcreteStrategy2 implements Strategy {
    //具體的算法實現
    @Override
    public void algorithmMethod() {
        System.out.println("ConcreteStrategy2");
    }
}

//策略上下文
class StrategyContext {
    private Strategy strategy;//持有一個策略實現的引用

    public StrategyContext(Strategy strategy) { //使用構造器注入具體的策略類
        this.strategy = strategy;
    }

    public void contextMethod() {
        strategy.algorithmMethod(); //調用策略實現的方法
    }
}

class Client {
    public static void main(String[] args) {
        Strategy concreteStrategy1 = new ConcreteStrategy1(); //建立具體測策略實現
        StrategyContext strategyContext = new StrategyContext(concreteStrategy1); //在建立策略上下文的同時,將具體的策略實現對象注入到策略上下文當中
        strategyContext.contextMethod(); //調用上下文對象的方法來完成對具體策略實現的回調
    }
}

策略模式(Strategy)類圖.png

  1. 策略接口角色IStrategy:用來約束一系列具體的策略算法,策略上下文角色ConcreteStrategy使用此策略接口來調用具體的策略所實現的算法。編碼

  2. 具體策略實現角色ConcreteStrategy:具體的策略實現,即具體的算法實現。設計

  3. 策略上下文角色StrategyContext:策略上下文,負責和具體的策略實現交互,一般策略上下文對象會持有一個真正的策略實現對象,策略上下文還可讓具體的策略實現從其中獲取相關數據,回調策略上下文對象的方法。code

  1. 策略模式就是把各個平等的具體實現進行抽象、封裝成爲獨立的算法類,而後經過上下文和具體的算法類來進行交互。
  2. 各個策略算法都是平等的,地位是同樣的,正是因爲各個算法的平等性,因此它們纔是能夠相互替換的。
  3. 雖然咱們能夠動態的切換各個策略,可是同一時刻只能使用一個策略

Observer/Event:事件模式

定義對象間的一種一對多(變化)的依賴關係,以便當一個對象(Subject)的狀態發生改變時候,全部依賴於它的對象都等到通知並自動更新server

/**
 * @author lillcol
 * 2019/6/13-23:38
 */
//被觀察者抽象類
public abstract class Subject {
    abstract void attack(Observer observer);//添加觀察者

    abstract void dettack(Observer observer);//移除觀察者

    abstract void notifyObserver();//通知觀察者

    abstract void operation();//被觀察者狀態變化
}

//被觀察者抽象類
abstract class AbstractSubject extends Subject {
    private List<Observer> observerList = new ArrayList<>(); //觀察者對象集合

    @Override
    void attack(Observer observer) {//添加觀察者
        observerList.add(observer);
    }

    @Override
    void dettack(Observer observer) {//移除觀察者
        observerList.remove(observer);
    }

    @Override
    void notifyObserver() {
        for (Observer observer : observerList) {
            observer.update();
        }
    }
}

//被觀察者實現類
class ConcreteSubject extends AbstractSubject {
    @Override
    void operation() {
        System.out.println("ConcreteSubject 要搞事情了");
        notifyObserver();   // 通知全部觀察者
    }
}

//觀察者抽象類
abstract class Observer {
    public String name;
    abstract void setName(String name);//設置名字

    abstract String getName();//獲取名字

    abstract void update();//觀察者更新方法
}

class ConcreteObserver1 extends Observer{

    @Override
    void setName(String name) {
        this.name=name;
    }

    @Override
    String getName() {
        return this.name;
    }

    @Override
    void update() {
        System.out.println("傘兵一號 ConcreteObserver1 準備就緒");
    }
}

class ConcreteObserver2 extends Observer{

    @Override
    void setName(String name) {
        this.name=name;
    }

    @Override
    String getName() {
        return this.name;
    }

    @Override
    void update() {
        System.out.println("傘兵二號 ConcreteObserver2 準備就緒");
    }
}
//測試案例:
class Test{
    public static void main(String[] args) {
        ConcreteSubject concreteSubject = new ConcreteSubject();
        ConcreteObserver1 concreteObserver1 = new ConcreteObserver1();
        ConcreteObserver2 concreteObserver2 = new ConcreteObserver2();
        concreteSubject.attack(concreteObserver1);
        concreteSubject.attack(concreteObserver2);
        concreteSubject.operation();
        System.out.println("------");
        concreteSubject.dettack(concreteObserver1);
        concreteSubject.operation();
    }
}
//輸出:
ConcreteSubject 要搞事情了
傘兵一號 ConcreteObserver1 準備就緒
傘兵二號 ConcreteObserver2 準備就緒
------
ConcreteSubject 要搞事情了
傘兵二號 ConcreteObserver2 準備就緒

觀察者模式-類圖.png

其實就是發佈訂閱模式,發佈者發佈信息,訂閱者獲取信息;
訂閱了就能收到信息,沒訂閱就收不到信息。

參考文檔:李建中-(23種設計模式) 本文爲原創文章,轉在請註明出處!!!!

相關文章
相關標籤/搜索