聊一聊設計模式(四)-- 行為型設計模式

ClericYi發表於2020-02-21

聊一聊設計模式(四)-- 行為型設計模式

前言

講完了結構型設計模式,接下里就是行為型設計模式了。

思維導圖

聊一聊設計模式(四)-- 行為型設計模式

策略模式

定義一系列的演算法,把每一個演算法封裝起來,並且使它們可相互替換。

聊一聊設計模式(四)-- 行為型設計模式

在初中寫關於多邊形的題目的時候,我們可能通過已知方法硬生生解答出來,也有可能用輔助線來幫助我們解題。這就是兩種解題策略。 下面用程式碼體現一下。

/**
 * 上下文
 * 根據傳入策略給出解決方法
 */
public class Context {
    private Strategy strategy;
    Context(Strategy strategy){
        this.strategy = strategy;
    }

    void solve(){
        strategy.solve();
    }
}

/**
 * 兩種策略方法
 * 1. 輔助線法
 * 2. 硬答
 */
public class SoftStrategy implements Strategy {
    @Override
    public void solve() {
        System.out.println("輔助線解答");
    }
}

public class HardStrategy implements Strategy {
    @Override
    public void solve() {
        System.out.println("硬生生解答");
    }
}

/**
 * 抽象策略角色
 */
public interface Strategy {
    void solve();
}
複製程式碼

根據不同的策略往上下文角色裡傳入物件,就能得到具體的實現方法。

模版方法模式

定義一個操作中的演算法框架,而將一些步驟延遲到子類中,使得子類不改變一個演算法的結構即可重定義演算法的某些特定步驟。

聊一聊設計模式(四)-- 行為型設計模式

模版方法模式中的角色:

  1. AbstractClass:抽象類,定義框架。
  2. ConcreteClass:具體實現類
/**
 * 模版抽象類
 * 定義了一套邏輯方法,而子類只負責繼承和完善。
 */
public abstract class AbstractPerson {
    public final void wakeup(){
        zhengyan();
        xianbeizi();
        qichuang();
        hook();
    }

    abstract void zhengyan();
    abstract void xianbeizi();
    abstract void qichuang();
    void hook(){}
}

/**
 * 具體實現類
 */
public class Me extends AbstractPerson {
    @Override
    void zhengyan() {
        System.out.println("睜開眼睛");
    }

    @Override
    void xianbeizi() {
        System.out.println("掀被子");
    }

    @Override
    void qichuang() {
        System.out.println("起床");
    }

    @Override
    void hook() {
        super.hook();
        System.out.println("又想睡了");
    }
}
複製程式碼

hook()方法,稱為鉤子方法,兩種實現方式。

  1. 在抽象類中是一個空函式,子類視情況進行覆蓋操作。
  2. boolean作為返回值的,對某個條件進行判定。

觀察者模式

定義物件間一種一對多的依賴關係,每當一個物件改變狀態時,則所有依賴於它的物件都會得到通知並被自動更新。

聊一聊設計模式(四)-- 行為型設計模式

該模式中的角色:

  1. Subject:抽象主題
  2. ConcreteSubject:具體主題。
  3. Observer:抽象觀察者。
  4. ConcreteObserver:具體觀察者。
/**
 * 抽象觀察者類
 */
public interface IObserver {
    void update(String message);
}

/**
 * 抽象主題類
 */
public interface ISubject {
    void add(IObserver observer);
    void remove(IObserver observer);
    void notify(String message);
}

/**
 * 具體觀察者類
 */
public class Observer implements IObserver {
    @Override
    public void update(String message) {
        System.out.println(message);
    }
}

/**
 * 具體主題類
 */
public class Subject implements ISubject {
    List<IObserver> list = new ArrayList<>();

    @Override
    public void add(IObserver observer) {
        list.add(observer);
    }

    @Override
    public void remove(IObserver observer) {
        list.remove(observer);
    }

    @Override
    public void notify(String message) {
        for(IObserver observer: list){
            observer.update(message);
        }
    }
}
複製程式碼

這個模式聽著優點奇怪,但是程式碼寫起來其實一點都不生疏。其實就是使用主題類儲存各個觀察者,出現變化的話就迴圈遍歷,慢慢通知。

這個模式在我的Android工具包的Network包中也有使用。

但是這個模式存在一個缺點,因為它是一個個進行通知的,那麼update()函式中是可能存在耗時操作的。這個時候,比較建議的就是開一個子執行緒去進行處理,這樣在Android中不會對UI執行緒產生過多的佔用。

以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。


相關文章推薦:

聊一聊設計模式(一)-- 六大原則

聊一聊設計模式(二)-- 建立型設計模式

聊一聊設計模式(三)-- 結構型行為型設計模式

相關文章