前言

讲完了结构型设计模式,接下里就是行为型设计模式了。

思维导图

策略模式

定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换。

在初中写关于多边形的题目的时候,我们可能通过已知方法硬生生解答出来,也有可能用辅助线来帮助我们解题。这就是两种解题策略。
下面用代码体现一下。

/**
 * 上下文
 * 根据传入策略给出解决方法
 */
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线程产生过多的占用。