设计模式(8)模板方法(讲解+应用)

java 4 2016-02-29 13:03
女装

目录

  1. 模板方法

  2. 为什么使用模板方法

  3. 模板方法应用实例

模板方法

模板方法:在一个方法中定义一个算法的框架,然后将该方法中的一些步骤延迟到子类中,使得再不改变算法的前提下,重新定义自己的算法。

看了模板方法的定义,可能感觉这和策略模式没有什么区别,都是对算法的封装,但是其差别在那里呢?

区别:策略模式是通过组合的方式将多个类的方法组合在一起,而模板方法是通过继承来实现的,即为在父类中有一个final的不可修改的方法,将我们的算法逻辑写在里面,然后其组合起来的算法可以在其子类中具体的根据实际情况去定义。

为什么要用模板方法

现在我们要实现一个流水线,这个流水线上,我们可以生产过的机器,而这些机器组成上是存在一些差别的,如果机器的种类不是很多,我们可以针对每一个机器都做一条流水线,但是如果机器种类很多,如果这些机器的出货时间是不同的,那么一旦第一批货出完,那么该机器的生产流水线就会闲置下来,利用率就会很低,以此类比,如果我们针对每种机型创建一个类,势必会使得我们的代码很臃肿,会有很多的重复代码存在,根据设计模式的基本原则,将不变的抽离出来,对变化的部分进行封装,通过这来使我们的代码更简洁的同时减少后期的维护成本。
因此我们可以这么写

//机器装配的基类
public abstract class Machine{
//机器装配的流程,final不可被复写,保证方装配算法不被破坏
    final void produce(){
        createFrame();
        addHead();
        addBody();
        if(ifDressup())
            dressUp();
    }
//创建框架
    public abstract void createFrame();
//添加一个机器头
    public abstract void addHead();
//添加一个机器的身子
    public abstract void addBody();
//为机器进行装扮
    public abstract void dressUp();
//判断是否为该机器进行装扮
    public boolean ifDressup(){
        return true;
    }

}
//继承自基类的一个子类
public class InflatableDoll{
    public void createFrame(){
        System.out.println("This is a Frame");
    }

    public void addBody(){
        System.out.println("This is a body");
    }

    public void dressUp(){
        System.out.println("This is a beautiful cloth");
    }

}

上述有注释的地方就不在此啰嗦了,上一篇结尾的时候要说下的一个钩子方法,这里提一下,这里的豆子方法就是ifDressup(),如果没有钩子方法,我们的的装配算法逻辑在父类中是final的,我们是不可以对其进行控制的,因此也就丧失了灵活性,当然我们希望能够在子类中对其进行控制,这样我们就可以更灵活的控制这个装配过程,因此出现了钩子方法,通过钩子方法将我们的子类和父类挂接起来,在我们的模板方法中将钩子方法作为一个装配条件,然后在我们的子类中根据我们自己的要求来覆写这个方法。、

模板方法应用实例

现实中,有那些例子呢?看到着,应该能够想起来一些什么,我们开发中的view,大多都是通过这种方式来进行的。以Android中的view为例子

public class View{
    /**
     * 钩子操作,空实现
     */
    protected void onDraw(Canvas canvas) {
    }
 
    /**
     *钩子操作,空实现
     */
    protected void dispatchDraw(Canvas canvas) {
    }
 
    //算法骨架
    public void draw(Canvas canvas) {
       if (!verticalEdges && !horizontalEdges) {
            // 步骤1
            if (!dirtyOpaque) onDraw(canvas);
 
            // 步骤2
            dispatchDraw(canvas);
 
            // 步骤3
            onDrawScrollBars(canvas);
 
            return;
        }
    }
    //... ...
}

View类

public class MyView extends View {
 
    public MyView(Context context) {
        super(context);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
 
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    }
     
}

通过上面的例子,我们可以看出我们的view控件绘制的一个流程。

下篇更新工厂模式,这个是当时看的时候最迷糊的一个了。

女装
文章评论