大话设计模式之---模板方法模式

在学习java的过程中,我们肯定听到过设计模式这名词,在行业中有这么一句话,若您能熟练的掌握23种设计模式,那么你便是大牛!

好了,废话不多说,今天我跟大家分享一下23种设计模式之一的  模板方法 设计模式

首先我们要知道什么是模板方法设计模式?

  模板方法设计模式就是定义一个操作中的算法骨架,而将一些实现步骤延迟到子类当中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

为什么要使用模板方法设计模式?  模板方法模式是比较简单的一种设计模式,但是它却是代码复用的一项基本的技术,在类库中尤其重要,它遵循“抽象类应当拥有尽可能多的行为,应当拥有尽可能少的数据”的重构原则。作为模板的方法要定义在父类中,在方法的定义中使用到抽象方法,而只看父类的抽象方法是根本不知道怎样处理的,实际做具体处理的是子类,在子类中实现具体功能,因此不同的子类执行将会得出不同的实现结果,但是处理流程还是按照父类定制的方式。这就是模板方法的要义所在,制定算法骨架,让子类具体实现。

在什么情况下使用?     -->算法或操作遵循相似的逻辑     -->重构时(把相同的代码抽取到父类中)

   -->重要、复杂的算法,核心算法设计为模板算法

接下来我们来看看到底怎么才能实现模板方法设计模式  我们以饮料机为示例的原型,每台饮料机都可以制作出不同的饮料,如同一台饮料机可  制作咖啡 还可以 制作茶  假如:制作咖啡的步骤如下:        制作茶的步骤如下:      1.将水煮沸                1.将水煮沸      2.用沸水泡咖啡              2.用沸水将茶叶煮五到六分钟      3.将咖啡倒入杯中             3.将茶水倒入杯中      4.假如糖块或牛奶             4.加入柠檬或不加任何东西那么,由上面的背景可见,我们制作咖啡和制作茶的步骤中 1 3是完全一致的,而2 4则是各自执行的各自的步骤所有我们就可以设计一个模板,来规范制作过程
/*
 * 抽象类   饮料机模板类
 */
public abstract class Template {
    /*
     * 制备饮料的模板方法
     * 封装了所有子类的共同遵循的算法框架
     */
    public final void driveTemplate(){ //这个模板必须用final修饰,因为不能允许子类修改这个模板框架,只能是修改特定的步骤
        //1.将水煮沸
        boilWater();
        //2. 炮制饮料
        blew();
        //3. 倒入杯中
        pourInCup();
       //4. 进入调味料
        addCondiments();
    }}
如上代码就是定义了一个制作饮料的模板,将具体的步骤都罗列出来了因为我们的步骤1和步骤3都是相同的所以我们可以将其实现方法定义为私有的,以减少代码的复杂度,而步骤2和步骤4则可定义为抽象方法,其实现交由其子类完成如:
/*
     * 基本方法,将水煮沸
     */
    private void boilWater() {
        System.out.println("将水煮沸");
    }

    /*
     * 基本方法,倒入杯中
     */
    private void pourInCup() {
        System.out.println("倒入杯中");
    }

    /*
     * 抽象的基本方法  加入调味料
     */
    public abstract void addCondiments();

    /*
     * 抽象的基本方法  炮制饮料
     */
    public abstract void blew();
这样我们就定义好了一个模板方法了,我们可以通过创建一个子类来继承自这个模板,重新其抽象方法 如  制作咖啡
/*
 * 制备咖啡的具体实现
 */
public class Coffee extends Template {

    //加入调味料
    @Override
    public void addCondiments() {
        System.out.println("加入糖和牛奶");
    }

    //炮制咖啡
    @Override
    public void blew() {
        System.out.println("用沸水冲泡咖啡");
    }

}
 或者是制作茶
/*
 * 制备茶的具体实现
 */
public class Tea extends Template {
    //添加调料
    @Override
    public void addCondiments() {
        System.out.println("加入柠檬");
    }
    //冲泡茶
    @Override
    public void blew() {
        System.out.println("用80度的热水浸泡茶叶5分钟");
    }

}

 这样我们在测试类中就能很清楚的看到结果了
//测试类
public class Test {
    public static void main(String[] args) {
        System.out.println("制备咖啡");
        Template t1=new Coffee();
        t1.driveTemplate();
        System.out.println("咖啡制备完成");
        System.out.println("=====================");
        System.out.println("制备茶");
        Template t2=new Tea();
        t2.driveTemplate();
        System.out.println("制备茶完成");
    }
}

测试结果如图

 
当然,如果我们现在有另外一种需求呢?就是我制作茶的时候不想要添加任何东西,这时候我们使用上面的方法是没法完成的,这时候我们就引出了模板方法设计模式中的另一个名词,  钩子函数我们可以使用钩子函数来判断是否要执行某一步的操作如:
/*
 * 抽象类   饮料机模板类
 */
public abstract class Template {
    /*
     * 制备饮料的模板方法
     * 封装了所有子类的共同遵循的算法框架
     */
    public final void driveTemplate(){ //这个模板必须用final修饰,因为不能允许子类修改这个模板框架,只能是修改特定的步骤
        //1.将水煮沸
        boilWater();
        //2. 炮制饮料
        blew();
        //3. 倒入杯中
        pourInCup();

        //钩子函数进行判定(例如茶不想加入调味料)
        if(isRight()){
            //4. 进入调味料
            addCondiments();
        }
    }

    /*
     * 基本方法,将水煮沸
     */
    private void boilWater() {
        System.out.println("将水煮沸");
    }

    /*
     * 基本方法,倒入杯中
     */
    private void pourInCup() {
        System.out.println("倒入杯中");
    }

    /*
     * 抽象的基本方法  加入调味料
     */
    public abstract void addCondiments();

    /*
     * 抽象的基本方法  炮制饮料
     */
    public abstract void blew();

    //钩子函数  判断用户是否要执行某些功能
    public boolean isRight(){
        return true;
    }

}

假如在制作茶的时候不想加任何东西,那么我们只需要在制作茶的子类中将钩子函数重写即可
/*
 * 制备茶的具体实现
 */
public class Tea extends Template {
    //添加调料
    @Override
    public void addCondiments() {
        System.out.println("加入柠檬");
    }
    //冲泡茶
    @Override
    public void blew() {
        System.out.println("用80度的热水浸泡茶叶5分钟");
    }
    //重写钩子函数 改变其值
    @Override
    public boolean isRight(){
        return false;
    }

}

这样的执行结果如图 这样就完成了我们的需求了

以上就是模板方法设计模式中的内容了,其他设计模式会在后续学到后再跟大家分享分享~~注:本人也是初学者,所以写得不好的地方望各位大牛勿怪,有不足的地方还望指出来,欢迎讨论!
				
时间: 2024-08-09 05:39:26

大话设计模式之---模板方法模式的相关文章

【大话设计模式】—— 模板方法模式

一.概念 上一篇文章刚刚讲了[大话设计模式]-- 原型模式,原型模式主要是通过Clone()方法,创建新的对象,免去了初始化的过程.模板方法模式也特别会"偷工减料",把不变的行为搬移到超类,去除子类中的重复代码,将代码的复用优势展现的淋漓尽致.它为我们提供了特定的结构和样式,我们只需关心填充数据内容就好,省心啊- 下面让我们来看一下它的准确定义: 模板方法(TemplateMethod)模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构

大话设计模式_模板方法模式(Java代码)

模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 简单描述:多个类的行为是差不多的,只是某些局部不一样,则交由父类中抽象出这些子类中相同的部分,父类中定义出不同的部分的接口(方法),这些不同部分的方法则由子类去实现,通过多态,实现代码的重用 大话设计模式中的截图: 例子代码: AbstractClass类: 1 package com.longsheng.templatemethod; 2 3 public

大话设计模式笔记 模板方法模式(常用)

当我们要完成在某一细节层次一致的一个过程或一系列步骤,但某个别步骤在详细的层次上实现不同时,我们通常考虑用模板方法模式来处理. 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势. package templateMethod; public abstract class Template { public abstract voi

设计模式之模板方法模式(Template Method)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

【设计模式】——模板方法模式

模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤.当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理. AbstractClas是抽象类,其实也就是一抽象模板,定义并实现了一个模板方法.这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现.顶级逻辑也有可能调用一些具体

大话设计模式_备忘录模式(Java代码)

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 简单描述:一个Memento类,代表Originator中要备份的属性.Originator负责生成备份和还原备份,CareTaker负责存储备份 大话设计模式中的截图: 例子代码: Memento类: 1 package com.longsheng.memento; 2 3 public class Memento { 4 5 private String sta

【大话设计模式】——代理模式

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持三种继承映射策略: 使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. 使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表

大话设计模式_解释器模式(Java代码)

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 简单描述:一个AbstractExpression类,多个子类,存在一个Interpret方法,转义Context对象的信息.客户端根据信息实例化不同的Expression类,并调用其转义方法(这个过程可以使用简单工厂+反射进行) 大话设计模式中的截图: 代码例子: 假设HTML代码解释器: (1)第一类标签<HTML>(开始)/<HEAD>(头信息)/<BODY&g

大话设计模式_原型模式(Java代码)

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 简单描述:即通过实现接口Cloneable重写方法clone(),使得创建新的拷贝对象不需要一个成员一个成员的重新复制,而且可以提高创建对象的效率 Java中要想实现拷贝使用clone()方法,类必须实现Cloneable接口,并且重写Object类中的clone()方法,调用父类的clone()方法即可实现浅复制 代码如下: WorkExperience类: 1 package com.longsheng.prototy