精华内容
参与话题
问答
  •  这一节主要来学习一下设计模式中的模板方法模式。我们先来看一个例子:假如现在老板让你做一个汽车的模型,要求只要完成基本功能即可,不考虑扩展性,那你会怎么做呢?我们首先会根据经验设计一个类图:  由这...

    1. 模板方法的一个实例

            这一节主要来学习一下设计模式中的模板方法模式。我们先来看一个例子:假如现在老板让你做一个汽车的模型,要求只要完成基本功能即可,不考虑扩展性,那你会怎么做呢?我们首先会根据经验设计一个类图:

           由这个类图可知,非常简单的实现了悍马车,该车有两个型号H1和H2。那现在我们开始实现这两个型号的悍马车,首先我们得把抽象类写好,然后两个不同的模型实现类通过简单的继承就可以实现要求。首先看看抽象类的代码:

     

    public abstract class HummerModel {
    	public abstract void start(); //发动
    	public abstract void stop();  //停止
    	public abstract void alarm(); //鸣笛
    	public abstract void engineBoom(); //轰鸣
    	public abstract void run(); //车总归要跑
    }

            简单到不行,下面我们来实现两个悍马的模型:

     

     

    //悍马H1
    public class HummerH1 implements HummerModel {
    
    	@Override
    	public void start() {
    		System.out.println("H1发动……");
    	}
    
    	@Override
    	public void stop() {
    		System.out.println("H1停止……");
    	}
    
    	@Override
    	public void alarm() {
    		System.out.println("H1鸣笛……");
    	}
    
    	@Override
    	public void engineBoom() {
    		System.out.println("H1轰鸣……");
    	}
    
    	@Override
    	public void run() {
    		this.start();
    		this.engineBoom();
    		this.alarm();
    		this.stop();
    	}
    }
    
    //悍马H2
    public class HummerH2 implements HummerModel {
    
        @Override
        public void start() {
            System.out.println("H2发动……");
        }
    
        @Override
        public void stop() {
            System.out.println("H2停止……");
        }
    
        @Override
        public void alarm() {
            System.out.println("H2鸣笛……");
        }
    
        @Override
        public void engineBoom() {
            System.out.println("H2轰鸣……");
        }
    
        @Override
        public void run() {
            this.start();
            this.engineBoom();
            this.alarm();
            this.stop();
        }
    }
    

            很明显,已经发现代码有点问题了,两个悍马的run方法完全相同。所以这个run方法应该出现在抽象类中,不应该在实现类中,抽象是所有子类的共性封装。所以我们修改一下抽象类:

     

     

    public abstract class HummerModel {
    	public abstract void start(); //发动
    	public abstract void stop();  //停止
    	public abstract void alarm(); //鸣笛
    	public abstract void engineBoom(); //轰鸣
    	public void run() { //车总归要跑
    		this.start();
    		this.engineBoom();
    		this.alarm();
    		this.stop();
    	}
    }

            这样两个实现类就不用实现run方法了,可以直接拿来用。其实,这就是模板方法模式。

     

    2. 模板方法模式的定义

            模板方法模式很简单,它的定义是:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses define certain steps of an algorithm without changing the algorithm's structure. 即定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可冲定义该算法的某些特定步骤。模板方法模式的通用类图如下:

            模板方法模式确实很简单,仅仅使用了java的继承机制,但是它是一个应用非常广泛的模式,其中AbstractClass叫做抽象模板,它的方法分为两类:基本方法(由子类去实现)和模板方法(可以有一个或多个,也就是一个框架,实现对基本方法的调度,完成固定的逻辑)。为了防止恶意的操作,一般模板方法上都添加上final关键字,不允许被覆写。我们来看一下AbstractClass模板:

     

    public abstract class AbstractClass {
    	//基本方法
    	protected abstract void doSomething();
    	protected abstract void doAnything();
    	//模板方法
    	public void templateMethod() {
    		//调用基本方法,完成相关的逻辑
    		this.doAnything();
    		this.doSomething();
    	}
    }

            具体实现类就不写了……

     

    3. 模板方法模式的优缺点

          优点:

            1)封装不变部分,扩展可变部分:把认为不变部分的算法封装到父类实现,可变部分则可以通过继承来实现,很容易扩展。

            2)提取公共部分代码,便于维护:上面悍马的例子就是个很好的解释。

            3)行为由父类控制,由子类实现。

          缺点:

            模板方法模式颠倒了我们平常的设计习惯:抽象类负责声明最抽象、最一般的事物属性和方法,实现类实现具体的事物属性和方法。在复杂的项目中可能会带来代码阅读的难度。

    4. 模板方法模式的扩展

            还是上面那个悍马的例子,现在老板说这车干嘛跑起来就要鸣笛,太吵了,难道不是应该让用户决定它是否要鸣笛么?好像确实是这样的……那好办,我们可以修改一下抽象模板类中的方法:

     

    public abstract class HummerModel {
    	protected abstract void start(); //发动
    	protected abstract void stop();  //停止
    	protected abstract void alarm(); //鸣笛
    	protected abstract void engineBoom(); //轰鸣
    	final public void run() { //车总归要跑
    		this.start();
    		this.engineBoom();
    		if(this.isAlarm()) {//想让它叫就叫,不想就不叫		
    			this.alarm();
    		}
    		this.stop();
    	}
    	protected boolean isAlarm() { //我们加了一个判断方法,默认返回true
    		return true;
    	}
    }

           我们在模板类中增加了一个判断方法来判断是否要鸣笛,现在就好办了,具体实现类只要重写这个方法就可以做到人为控制是否要鸣笛了,下面我们来看一下实现类:

     

    public class HummerH1 extends HummerModel {
    
    	private boolean alarmFlag = true; //判断标记
    	@Override
    	public void start() {
    		System.out.println("H1发动……");
    	}
    
    	@Override
    	public void stop() {
    		System.out.println("H1停止……");
    	}
    
    	@Override
    	public void alarm() {
    		System.out.println("H1鸣笛……");
    	}
    
    	@Override
    	public void engineBoom() {
    		System.out.println("H1轰鸣……");
    	}
    	
    	@Override
    	protected boolean isAlarm() { //覆写isAlarm方法,返回判断标记
    		return this.alarmFlag;
    	}
    	
    	public void setAlarm(boolean isAlarm) { //设置判断标记
    		this.alarmFlag = isAlarm;
    	}
    	
    }

            这个实现很好,我们在实现类中定义一个判断标记,然后对外提供一个public接口setAlarm来让外界设置这个判断标记,这就像是开关一样,想让它ture和false都行。这个isAlarm方法俗称钩子方法。有了钩子方法的模板方法模式才算完美,大家可以想象一下,由子类的一个方法返回值决定公共部分的执行结果,这个是很有吸引力的。我们来测试一下:

     

     

    public class Test {
    	public static void main(String[] args) throws IOException {
    		System.out.println("----H1型悍马----");
    		System.out.println("是否需要喇叭声响? 0-不需要  1-需要");
    		String type = new BufferedReader(new InputStreamReader(System.in)).readLine();
    		HummerH1 h1 = new HummerH1();
    		if(type.equals("0")) {
    			h1.setAlarm(false);
    		}
    		h1.run();
    	}
    }

            当输入不同的指令后,就会决定不同的动作:即要不要鸣笛,至此,这个模板方法模式就介绍完了。

            相关阅读:http://blog.csdn.net/column/details/des-pattern.html

    文末福利:“程序员私房菜”,一个有温度的公众号~ 
    程序员私房菜

    _____________________________________________________________________________________________________________________________________________________

    -----乐于分享,共同进步!

    -----更多文章请看:http://blog.csdn.net/eson_15

    展开全文
  • 模板方法模式深度解析(一)

    万次阅读 多人点赞 2012-12-15 20:52:32
    1. 模板方法模式概述 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中...

    1. 模板方法模式概述

           在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么?吃面条和吃满汉全席可大不相同,如图1所示:

    1 请客吃饭示意图

            在软件开发中,有时也会遇到类似的情况,某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点单”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃面条”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性和可扩展性。

           模板方法模式定义如下:

    模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

     

    Template Method Pattern:  Define the skeleton of an algorithm in an  operation, deferring some steps to subclasses. Template Method lets  subclasses redefine certain steps of an algorithm without changing the  algorithm's structure.

           模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式

           模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。

     

    2. 模板方法模式结构与实现

    2.1 模式结构

          模板方法模式结构比较简单,其核心是抽象类和其中的模板方法的设计,其结构如图2所示:

    2 模板方法模式结构图

          由图2可知,模板方法模式包含如下两个角色:

           (1) AbstractClass(抽象类)在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

           (2) ConcreteClass(具体子类)它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

     

    2.2 模式实现

           在实现模板方法模式时,开发抽象类的软件设计师和开发具体子类的软件设计师之间可以进行协作。一个设计师负责给出一个算法的轮廓和框架,另一些设计师则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法即为基本方法,而将这些基本方法汇总起来的方法即为模板方法,模板方法模式的名字也因此而来。下面将详细介绍模板方法和基本方法:

           1. 模板方法

           一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类,而不是接口。

             2. 基本方法

           基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)

           (1) 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。在C#语言里一个抽象方法以abstract关键字标识。

           (2) 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

           (3) 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。

           在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是bool类型的,这类方法名一般为IsXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行,如下代码片段所示:

    ……
    //模板方法
    public void TemplateMethod() 
    {
    Open();
    Display();
    //通过钩子方法来确定某步骤是否执行
    if (IsPrint()) 
    {
        Print();
    }
    }
    
    //钩子方法
    public bool IsPrint()
    {
        return true;
    }
    ……

            在代码中IsPrint()方法即是钩子方法,它可以决定Print()方法是否执行,一般情况下,钩子方法的返回值为true,如果不希望某方法执行,可以在其子类中覆盖钩子方法,将其返回值改为false即可,这种类型的钩子方法可以控制方法的执行,对一个算法进行约束。

           还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,这类钩子方法的好处在于子类如果没有覆盖父类中定义的钩子方法,编译可以正常通过,但是如果没有覆盖父类中声明的抽象方法,编译将报错。

           在模板方法模式中,抽象类的典型代码如下:

    abstract class AbstractClass 
    {
    //模板方法
    public void TemplateMethod() 
    {
            PrimitiveOperation1();
            PrimitiveOperation2();
            PrimitiveOperation3();
    }
    
    //基本方法—具体方法
    public void PrimitiveOperation1() 
    {
        //实现代码
    }
    
    //基本方法—抽象方法
        public abstract void PrimitiveOperation2();    
    
    //基本方法—钩子方法
    public virtual void PrimitiveOperation3()   
    {  }
    }

            在抽象类中,模板方法TemplateMethod()定义了算法的框架,在模板方法中调用基本方法以实现完整的算法,每一个基本方法如PrimitiveOperation1()PrimitiveOperation2()等均实现了算法的一部分,对于所有子类都相同的基本方法可在父类提供具体实现,例如PrimitiveOperation1(),否则在父类声明为抽象方法或钩子方法,由不同的子类提供不同的实现,例如PrimitiveOperation2()PrimitiveOperation3()

            可在抽象类的子类中提供抽象步骤的实现,也可覆盖父类中已经实现的具体方法,具体子类的典型代码如下:

    class ConcreteClass : AbstractClass 
    {
    public override void PrimitiveOperation2() 
    {
        //实现代码
    }
    
    public override void PrimitiveOperation3() 
    {
        //实现代码
    }
    }

           在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。

      【作者:刘伟   http://blog.csdn.net/lovelion

    展开全文
  • 前言今天我来全面总结一下Android开发中最常用的设计模式 - 模板方法模式。 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(SimpleFactoryPattern...

    前言

    今天我来全面总结一下Android开发中最常用的设计模式 - 模板方法模式。

    其他设计模式介绍
    1分钟全面了解“设计模式”
    单例模式(Singleton) - 最易懂的设计模式解析
    简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析
    工厂方法模式(Factory Method)- 最易懂的设计模式解析
    抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析
    策略模式(Strategy Pattern)- 最易懂的设计模式解析
    适配器模式(Adapter Pattern)- 最易懂的设计模式解析
    代理模式(Proxy Pattern)- 最易懂的设计模式解析
    模板方法模式(Template Method) - 最易懂的设计模式解析
    建造者模式(Builder Pattern)- 最易懂的设计模式解析
    外观模式(Facade Pattern) - 最易懂的设计模式解析


    目录

    模板方法模式.jpg


    1. 介绍

    1.1 定义

    定义一个模板结构,将具体内容延迟到子类去实现。

    1.2 主要作用

    在不改变模板结构的前提下在子类中重新定义模板中的内容。

    模板方法模式是基于”继承“的;

    1.3 解决的问题

    • 提高代码复用性
      将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中
    • 实现了反向控制
      通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合“开闭原则”

    2. 模式原理

    2.1 UML类图 & 组成

    UML类图

    2.2 实例讲解

    接下来我用一个实例来对模板方法模式进行更深一步的介绍。
    a. 实例概况

    • 背景:小成希望学炒菜:手撕包菜 & 蒜蓉炒菜心
    • 冲突:两道菜的炒菜步骤有的重复有的却差异很大,记不住
    • 解决方案:利用代码记录下来

    b. 使用步骤
    步骤1: 创建抽象模板结构(Abstract Class):炒菜的步骤

    
    public  abstract class Abstract Class {  
    //模板方法,用来控制炒菜的流程 (炒菜的流程是一样的-复用)
    //申明为final,不希望子类覆盖这个方法,防止更改流程的执行顺序 
            final void cookProcess(){  
            //第一步:倒油
            this.pourOil();
            //第二步:热油
             this.HeatOil();
            //第三步:倒蔬菜
             this.pourVegetable();
            //第四步:倒调味料
             this.pourSauce();
            //第五步:翻炒
             this.fry();
        }  
    
    //定义结构里哪些方法是所有过程都是一样的可复用的,哪些是需要子类进行实现的
    
    //第一步:倒油是一样的,所以直接实现
    void pourOil(){  
            System.out.println("倒油");  
        }  
    
    //第二步:热油是一样的,所以直接实现
        void  HeatOil(){  
            System.out.println("热油");  
        }  
    
    //第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
    //所以声明为抽象方法,具体由子类实现 
        abstract void  pourVegetable();
    
    //第四步:倒调味料是不一样的(一个下辣椒,一个是下蒜蓉)
    //所以声明为抽象方法,具体由子类实现 
        abstract void  pourSauce();
    
    
    //第五步:翻炒是一样的,所以直接实现
        void fry();{  
            System.out.println("炒啊炒啊炒到熟啊");  
        }  
    }
    

    步骤2: 创建具体模板(Concrete Class),即”手撕包菜“和”蒜蓉炒菜心“的具体步骤

    //炒手撕包菜的类
      public class ConcreteClass_BaoCai extend  Abstract Class{
        @Override
        public void  pourVegetable(){  
            System.out.println(”下锅的蔬菜是包菜“);  
        }  
        @Override
        public void  pourSauce(){  
            System.out.println(”下锅的酱料是辣椒“);  
        }  
    }
    //炒蒜蓉菜心的类
      public class ConcreteClass_CaiXin extend  Abstract Class{
        @Override
        public void  pourVegetable(){  
            System.out.println(”下锅的蔬菜是菜心“);  
        }  
        @Override
        public void  pourSauce(){  
            System.out.println(”下锅的酱料是蒜蓉“);  
        }  
    }
    
    

    步骤3:客户端调用-炒菜了

    public class Template Method{
      public static void main(String[] args){
    
    //炒 - 手撕包菜
        ConcreteClass_BaoCai BaoCai = new ConcreteClass_BaoCai();
        BaoCai.cookProcess();
    
    //炒 - 蒜蓉菜心
      ConcreteClass_ CaiXin = new ConcreteClass_CaiXin();
        CaiXin.cookProcess();
        }
            
    }
       
    

    结果输出

    倒油
    热油
    下锅的蔬菜是包菜
    下锅的酱料是辣椒
    炒啊炒啊炒到熟
    
    倒油
    热油
    下锅的蔬菜是菜心
    下锅的酱料是蒜蓉
    炒啊炒啊炒到熟
    

    通过上述这个常见的生活例子,我相信你已经完全明白了模板方法模式的原理了!!


    3. 优缺点

    在全面解析完模板方法模式后,我来分析下其优缺点:

    3.1 优点

    • 提高代码复用性
      将相同部分的代码放在抽象的父类中
    • 提高了拓展性
      将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为
    • 实现了反向控制
      通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合“开闭原则”

    3.2 缺点

    引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。


    4. 应用场景

    • 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;
    • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复;
    • 控制子类的扩展。

    5. 总结

    • 本文主要对模板方法模式进行了全面介绍
    • 接下来将介绍其他设计模式,感兴趣的同学可以继续关注carson_ho的微信公众号
      示意图
      示意图

    请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!

    相关文章阅读
    单例模式(Singleton) - 最易懂的设计模式解析
    简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析
    工厂方法模式(Factory Method)- 最易懂的设计模式解析
    抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析
    策略模式(Strategy Pattern)- 最易懂的设计模式解析
    适配器模式(Adapter Pattern)- 最易懂的设计模式解析
    代理模式(Proxy Pattern)- 最易懂的设计模式解析
    模板方法模式(Template Method) - 最易懂的设计模式解析
    建造者模式(Builder Pattern)- 最易懂的设计模式解析
    外观模式(Facade Pattern) - 最易懂的设计模式解析

    展开全文
  • 模板方法模式

    千次阅读 2013-09-22 14:53:03
    模板方法模式 定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤 将主要的方法定义为final,防止子类修改算法骨架,将...

    模板方法模式

    定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。将主要的方法定义为final,防止子类修改算法骨架,将子类必须实现的方法定义为abstract。而普通的方法(无final或abstract修饰)则称之为钩子。
    钩子作用:
    1)作为可选内容,子类可以重写或者置之不理
    2)让子类有机会对模板方法中即将发生的或者已经发生的步骤做出反应
    3)作为控制条件,使得子类可以影响到抽象类中的算法流程
    角色:模板抽象父类,模板子类
    优点
    1)模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。
    2)模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
    3)模板方法模式导致一种反向的控制结构,这种结构有时被称为“好莱坞法则” ,即“别找我们,,我们找你”通过一个父类调用其子类的操作(而不是相反的子类调用父类),通过对子类的扩展增加新的行为,符合“开闭原则”
    缺点
    每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高。
    总结
    1)模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。
    2)板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

    3)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

    代码示例

    /**
     * 模板方法中的父类,prepare方法定义了算法步骤,不同的饮料需要实现不同的brew,并可以选择是否覆盖food方法
     * 
     * @author sky
     * 
     */
    public abstract class Beverage {
    
    	/**
    	 * 准备饮料的过程,烧水,冲泡,倒杯,搭配糕点
    	 */
    	final public void prepare() {
    		boilWater();
    		brew();
    		pourInCup();
    		food();
    	}
    
    	final public void boilWater() {
    		System.out.println("烧水");
    	}
    
    	abstract void brew();
    
    	final public void pourInCup() {
    		System.out.println("将饮料倒入杯子里");
    	}
    
    	public void food() {
    		System.out.println("搭配一点糕点");
    	}
    
    }
    
    /**
     * 咖啡,实现了brew方法
     * 
     * @author sky
     * 
     */
    public class Coffee extends Beverage {
    
    	@Override
    	void brew() {
    		System.out.println("冲咖啡");
    	}
    
    }
    
    /**
     * 茶,实现了brew方法,重写了food方法
     * 
     * @author sky
     * 
     */
    public class Tea extends Beverage {
    
    	@Override
    	public void food() {
    		System.out.println("喝茶不需要搭配糕点");
    	}
    
    	@Override
    	void brew() {
    		System.out.println("冲茶");
    	}
    
    }
    
    /**
     * 测试类
     * 
     * @author sky
     * 
     */
    public class Test {
    
    	public static void main(String[] args) {
    		System.out.println("---茶---");
    		Beverage tea = new Tea();
    		tea.prepare();
    		System.out.println("---咖啡---");
    		Beverage coffee = new Coffee();
    		coffee.prepare();
    	}
    
    }
    
    输出:
    	---茶---
    	烧水
    	冲茶
    	将饮料倒入杯子里
    	喝茶不需要搭配糕点
    	---咖啡---
    	烧水
    	冲咖啡
    	将饮料倒入杯子里
    	搭配一点糕点


    展开全文
  • 介绍模板方法模式 源码分析模板方法模式的典型应用 Servlet 中的模板方法模式 Mybatis BaseExecutor接口中的模板方法模式 模板方法模式 在程序开发中,经常会遇到这种情况:某个方法要实现的算法需要多个步骤,...
  • 模板方法模式

    2015-03-20 15:54:15
    大话设计模式中的模式,模板方法模式的源码,帮助学习设计模式的小伙伴。
  • Adapter Pattern适配器模式细说适配器模式细说适配器模式 细说适配器模式 提示: 博主:章飞 _906285288的博客 博客地址:http://blog.csdn.net/qq_29924041 细说适配器模式 ...
  • 模板方法模式

    2019-11-01 16:13:18
    摘录自《大话设计模式》 第一版代码: 试卷父类代码 学生类代码 客户端代码 仔细看看,两个学生的类里面还是存在相同的东西。比如都有‘base.TestQuestion()’,还有‘Console.WriteLine(" 答案:")’...
  • 模板方法模式

    千次阅读 2019-04-16 11:11:12
    模板方法模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。例如,一个人每天会起床、吃饭、做事、睡觉等,其中“吃饭”和“做事”的内容每天可能不同。 意图:定义一个操作中的算法的...
  • 模板方法模式:           定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。  &...
  • 1.模板方法模式的概念 模板方法模式,定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 2.模板方法模式的结构 Abstract...
  • 模板方法模式

    2019-01-14 00:05:13
    所谓模板方法模式就是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 模板方法模式是基于继承的代码复用技术的。在模板...
  • 模板方法模式

    2020-04-15 09:51:32
    模板方法模式 定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤。 package no3; public class test7 { public...
  • 模板方法模式 java

    千次阅读 2018-01-02 21:49:24
    1. 模板方法模式概述 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 –> 吃东西 –> 买单。在这三个步骤中...
  • 模板方法模式

    千次阅读 2016-10-16 16:18:54
    模板方法使得子类可以在不改变一个算法的结构的前提下重定义该算法的某些特定步骤. 处理某个流程的骨架代码已经具备, 但其中某节点的具体实现暂不确定, 此时可采用模板方法, 将该节点的代码实现转移给子类完成.
  • Java设计模式-模板方法模式

    千次阅读 2019-03-26 14:56:10
    模板方法模式
  • 模板方法模式VS建造者模式

    千次阅读 2012-12-23 22:30:20
    今天再来两个设计模式的对决,模板方法模式VS建造者模式。 首先,看看模板方法模式的定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法...
  • 模板方法模式例子

    千次阅读 2016-12-05 17:14:11
    原文地址:http://www.cnblogs.com/jenkinschan/p/5768760.html一、概述 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中...
  • 本文出自: 【HansChen...设计模式之模板方法模式和策略模式概述我们知道,OOP三个基本特征是:封装、继承、多态。通过继承,我们可以基于差异编程,也就是说,对于一个满足我们大部分需求的类,可以创建它的一个子类并
  • 模板方法模式

    千次阅读 2016-12-13 22:13:49
    模板方法模式属于行为类模式。模板方法的组成类图: 如图所示,模板方法模式主要由AbstractClass(抽象类)和ConcreteClass(具体子类)组成。 AbstractClass(抽象类):定义一个模板,亦称为算法的“骨架”,...

空空如也

1 2 3 4 5 ... 20
收藏数 296,325
精华内容 118,530
关键字:

模板方法模式