美文网首页
模板方法及观察者模式

模板方法及观察者模式

作者: 某昆 | 来源:发表于2018-11-03 12:52 被阅读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,告诉改变。

    相关文章

      网友评论

          本文标题:模板方法及观察者模式

          本文链接:https://www.haomeiwen.com/subject/wdjkxqtx.html