前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈几种设计模式--模板模式

浅谈几种设计模式--模板模式

作者头像
田维常
发布2019-07-16 10:44:47
3770
发布2019-07-16 10:44:47
举报

概述

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

类结构图

解决问题

模板方法就是提供一个算法框架,框架里面的步骤有些是父类已经定好的,有些需要子类自己实现。相当于要去办一件事情,行动的流程已经定好了,但有些步骤需要自己去做,而有些步骤可能别人帮我们做了。

就拿建网站来说,一般的程序是购买域名-->购买空间-->上传网站-->备案-->审核,每个网站的创建必须经过这样的固定程序,但除了审核不用建站者关心,其他的步骤都要建站者自己去完成。

应用实例

现在我们很多家庭都有了豆浆机,豆浆的营养价值不用我多说了。

制作豆浆的程序简单点来说就是

选材--->添加配料--->浸泡--->放到豆浆机打碎,通过添加不同的配料,可以制作出不同口味的豆浆,但是选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的。

代码

//豆浆类,抽象类
public abstract class SoyaMilk {
    //这是模板方法,用final修饰,不允许子类覆盖。模板方法定义了制作豆浆的程序
    final void  prepareRecipe(){
        selectMaterial();
        addCondiments();
        soak();
        beat();
    }
    //选材方法,选择黄豆
    void selectMaterial(){
         System.out.println("第一步、选择好了新鲜黄豆");
    }
    //可以添加不同的配料,在这里设置为抽象方法,子类必须实现
    abstract void addCondiments();
    //浸泡
    void soak(){
        System.out.println("第三步、黄豆和配料开始浸泡,大概需要5个小时");
    }
    //放到豆浆机打碎
    void beat(){
        System.out.println("第四步、黄豆的配料放到豆浆机打碎");
    }
}
//红枣豆浆
public class ReddatesSoyaMilk extends SoyaMilk{
    //实现父类的添加配料方法
    @Override
    void addCondiments() {
        System.out.println("第二步、添加红枣配料");
   } 
}


//核桃豆浆
public class NutSoyaMilk extends SoyaMilk{
    //实现父类的添加配料方法
    @Override
    void addCondiments() {
        System.out.println("第二步、添加核桃配料");      
    }
}

测试制作豆浆

public class SoyaMilkTest {
    public static void main(String[] args){
        //制作红枣豆浆
        System.out.println();
        System.out.println("-----制作红枣豆浆步骤-------");
        SoyaMilk reddatesSoyaMilk = new ReddatesSoyaMilk();
        reddatesSoyaMilk.prepareRecipe();
         
        //制作核桃豆浆
        System.out.println();
        System.out.println("-----制作核桃豆浆步骤-------");
        SoyaMilk nutSoyaMilk = new NutSoyaMilk();
        nutSoyaMilk.prepareRecipe();
    }
}

运行结果

钩子方法

在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”。我们还是用上面做豆浆的例子来讲解。

//这是模板方法,用final修饰,不允许子类覆盖。模板方法定义了制作豆浆的程序
    final void  prepareRecipe(){
        selectMaterial();
        //判断是否添加配料
        if(customerWantsCondiments()){
            addCondiments();
        }      
        soak();
        beat();
    }
    //钩子方法,是否添加配料
    boolean customerWantsCondiments(){
        return true;
    }
//制作纯豆浆,不添加任何配料
public class PureSoyaMilk extends SoyaMilkWithHook{
 
    @Override
    void addCondiments() {
         
    }
     
    //覆盖钩子方法,不添加配料
    @Override
    boolean customerWantsCondiments(){
        return false;
    }
}
//测试类:
public class PureSoyaMilkTest {
    public static void main(String[] args){
        //制作纯豆浆
        System.out.println();
        System.out.println("-----制作纯豆浆步骤-------");
        SoyaMilkWithHook pureSoyaMilk = new PureSoyaMilk();
        pureSoyaMilk.prepareRecipe();
    }
}

运行结果:

优缺点

1

优点

(1)、算法只存在于一个地方,也就是在父类中,容易修改。需要修改算法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改。

(2)、实现了最大化代码复用。父类的模板方法和已实现的某些步骤会被子类继承而直接使用。

(3)、既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现。

(4)、提供了一个基本框架,容易扩展子类。模板方法有框架控制如何做事情,而由使用框架的人指定框架算法中每个步骤的细节。子类只要继承父类,实现抽象方法,就可以使用父类的算法。

2

缺点

模板方法使用继承方式复用代码,如果要在基本算法里面增加一个步骤,而该步骤是抽象的话,每个子类都要修改代码,实现这个步骤。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
网站建设
网站建设(Website Design Service,WDS),是帮助您快速搭建企业网站的服务。通过自助模板建站工具及专业设计服务,无需了解代码技术,即可自由拖拽模块,可视化完成网站管理。全功能管理后台操作方便,一次更新,数据多端同步,省时省心。使用网站建设服务,您无需维持技术和设计师团队,即可快速实现网站上线,达到企业数字化转型的目的。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档