模板方法及观察者模式

2018-11-03  本文已影响25人  某昆

1、本文主要内容

本文主要讲两个设计模式,模板方法以及观察者模式,模板方法也是个非常有意思的设计模式,它强调的是模板以及子类的微调。观察者模式,对于我们来说则是非常熟悉的,在android中设置的种类listener都是观察者模式,因此本文不详述它了。

1、模板方法定义

模板方法:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤

模板方法UML类图

模板方法,它强调的是父类已经将算法的步骤确定好了,但步骤中的某些细节让子类自己实现。例如,泡茶或泡咖啡,大概都分成4个步骤 :

这种情况就可以使用模板方法,因为步骤基本确定(4个步骤),只有细节不同,接下来我们来看具体的代码示例。

3、模板方法示例

饮料超类:

public abstract class Drinks {

protected void boilWater(){
    System.out.println("烧水了");
}

protected abstract void brew();

protected void pourInCup() {
    System.out.println("倒入杯中");
}

protected abstract void addCondiments();

protected void hook(){};

public final void prepareRecipe(){
    boilWater();
    brew();
    pourInCup();
    addCondiments();
    hook();
}
}

茶:

public class Tee extends Drinks{

@Override
protected void brew() {
    System.out.println("冲泡茶叶");
}

@Override
protected void addCondiments() {
    System.out.println("添加一块柠檬");
}
}

咖啡:

public class Coffee extends Drinks{

@Override
protected void brew() {
    System.out.println("冲泡咖啡");
}

@Override
protected void addCondiments() {
    System.out.println("添加糖,牛奶");
}

@Override
protected void hook() {
    System.out.println("再添加一点椰粉");
}
}

接下来看人怎么冲泡了:

public class Client {

public static void main(String[] args) {
    Coffee coffee = new Coffee();
    coffee.prepareRecipe();
    System.out.println("----------------");
    Tee tee = new Tee();
    tee.prepareRecipe();
}
}

最终的结果如下:

烧水了
冲泡咖啡
倒入杯中
添加糖,牛奶
再添加一点椰粉
----------------
烧水了
冲泡茶叶
倒入杯中
添加一块柠檬

示例代码较为简单,注意,在Drinks超类中,我们定义了一个hook方法,中文名叫钩子函数,因为模板方法中已经为了我们定义好步骤了,如果我们要再加额外步骤呢?此时就可以用上hook函数了,比如在咖啡中,用户还要再加点椰粉。

hook函数,上述的做法只是其中之一,如果思维再开放一点,只要是能改变或者影响整流流程的,都算是钩子函数。比如,用户喝茶,并不需要加柠檬,我们可以重写Tee类中的 addCondiments ,根据客户需要,不要我们就不添加,这也算是钩子函数

钩子函数的意义在于,超类已经定好整个算法框架了,能够让子类有更大的灵活以及自由度。

3、观察者模式

观察者模式非常常见,一般对应的形式为一对多,也有一对一的,比如 view 的点击事件。它的UML图为:

一般subject类中提供注册以及反注册Observer的方法,当改变发生时,subject 则调用自己的成员变量 Observer,告诉改变。

上一篇下一篇

猜你喜欢

热点阅读