首页 > 编程语言 >设计模式-模板模式在Java中的使用示例-悍马模型制造示例

设计模式-模板模式在Java中的使用示例-悍马模型制造示例

时间:2023-04-22 19:37:29浏览次数:48  
标签:Java 示例 悍马 void System protected 设计模式 public 模板


场景

设计模式-模板模式在Java中的使用示例:

设计模式-模板模式在Java中的使用示

上面整理了模板模式的使用示例,为加强理解特记录另一个使用示例,

以下示例摘自设计模式之禅第二版。

模板方法模式

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

抽象模板方法分为两类: 基本方法(也叫作基本操作,是由子类实现的方法,并且在模板中被调用) 和

模板方法(可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑)。

注:

博客:质的博构之路,SpringBoot领域博主

实现

模板模式通用代码

1、抽象模板类

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

2、具体模板类1

//具体模板类
public class ConcreteClass1 extends AbstractClass{
    @Override
    protected void doSomething() {
        //业务逻辑处理
    }

    @Override
    protected void doAnything() {
        //业务逻辑处理
    }
}

3、具体模板类2

//具体模板类
public class ConcreteClass2 extends AbstractClass{
    @Override
    protected void doSomething() {
        //业务逻辑处理
    }

    @Override
    protected void doAnything() {
        //业务逻辑处理
    }
}

4、场景类

//场景类
public class Client {
    public static void main(String[] args) {
        AbstractClass class1 = new ConcreteClass1();
        AbstractClass class2 = new ConcreteClass2();
        //调用模板方法
        class1.templateMethod();
        class2.templateMethod();
    }
}

模板模式示例-悍马模型制作演示

1、悍马车有两个型号,H1和H2,实现抽象悍马模型

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();
    }
}

2、悍马H1具体模板类

public class HummerH1Model extends 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引擎轰轰响");
    }
}

3、悍马H2具体模板类

public class HummerH2Model extends 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("悍马H1引擎哔哔响");
    }
}

4、悍马场景类

在抽象的悍马模型上已经定义了run方法的执行规则。

场景类实现的任务就是把生产出的模型展现给客户。

public class HummerClient {
    public static void main(String[] args) {
        //某公司要H1型号的悍马
        HummerModel h1 = new HummerH1Model();
        //H1模型展示
        h1.run();
    }
}

模板模式示例-悍马模型需求扩展改造

1、客户需求更改,提出H1型号的悍马喇叭想让它响就响,H2的喇叭不要有声音。

在抽象类中新增一个实现方法isAlarm,确定各个型号的悍马是否需要声音,由各个实现类覆写该方法,

同时其它的基本方法由于不需要对外提供访问,因此也设计为protected类型。

public abstract class HummerExtendModel {
    /**
     * 首先这个模型要能发动起来,别管是手摇发动,还是电力发动,反正是要能够发动起来,那这个实现要在实现类里了
     */
    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(){
        return true;
    }
}

2、H1扩展具体模板类

public class HummerH1ExtendModel extends HummerExtendModel{
    //要响喇叭
    private boolean alarmFlag = true;

    @Override
    protected void start() {
        System.out.println("悍马H1启动");
    }

    @Override
    protected void stop() {
        System.out.println("悍马H1停止");
    }

    @Override
    protected void alarm() {
        System.out.println("悍马H1鸣笛");
    }

    @Override
    protected void engineBoom() {
        System.out.println("悍马H1引擎轰轰响");
    }

    protected boolean isAlarm(){
        return this.alarmFlag;
    }
    //要不要响喇叭,是由客户来决定的
    public void setAlarm(boolean isAlarm){
        this.alarmFlag = isAlarm;
    }
}

3、H2具体模板类

public class HummerH2ExtendModel extends HummerExtendModel{

    @Override
    protected void start() {
        System.out.println("悍马H2启动");
    }

    @Override
    protected void stop() {
        System.out.println("悍马H2停止");
    }

    @Override
    protected void alarm() {
        System.out.println("悍马H2鸣笛");
    }

    @Override
    protected void engineBoom() {
        System.out.println("悍马H2引擎轰轰响");
    }

    //默认是没有喇叭的
    protected boolean isAlarm(){
        return false;
    }

}

4、场景类

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

总结

模板方法模式的优点

封装不变部分,扩展可变部分
把认为是不变部分的算法封装到父类实现,而可变部分的则可以通过继承来继续扩展。在悍马模型例子中,是不是就非常容易扩展?例如增加一个H3型号的悍马模型,很容易呀,增加一个子类,实现父类的基本方法就可以了。

提取公共部分代码,便于维护
我们例子中刚刚走过的弯路就是最好的证明,如果我们不抽取到父类中,任由这种散乱的代码发生,想想后果是什么样子?维护人员为了修正一个缺陷,需要到处查找类似的代码!

行为由父类控制,子类实现
基本方法是由子类实现的,因此子类可以通过扩展的方式增加相应的功能,符合开闭原则。

模板方法模式的缺点

按照我们的设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法。但是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,而且也会让新手产生不适感。

模板方法模式的使用场景

- 多个子类有公有的方法,并且逻辑基本相同时。
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
- 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见“模板方法模式的扩展”)约束其行为。

标签:Java,示例,悍马,void,System,protected,设计模式,public,模板
From: https://blog.51cto.com/BADAOLIUMANGQZ/6215466

相关文章

  • java -- 网络编程
    软件结构C/S结构:全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。网络通讯协议网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间......
  • Java异常类层次结构?
    Throwable是Java语言中所有错误与异常的超类。Error类及其子类:程序中无法处理的错误,表示运行应用程序中出现了严重的错误。Exception程序本身可以捕获并且可以处理的异常。Exception这种异常又分为两类:运行时异常和编译时异常。运行时异常都是RuntimeException类......
  • Java中ArrayList的遍历与删除元素方式总结
    在Java编程中,我们经常需要对数据结构进行遍历操作,并根据业务需求删除部分元素。而数组列表(ArrayList)是集合类中的一种,它可以动态地添加和删除元素,非常适合在程序中使用。本篇博客将总结ArrayList中的两种遍历和删除元素的方式。在下面的示例代码中,我们先定义了一个ArrayList对象,......
  • java下载pdf等静态文件
    java下载pdf等静态文件  packagecom.example.climbnumber;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.URL;importjava.net.URLConnection;importjava.util.zip.GZIPInputStream;publicclass......
  • Redis 的Java客户端——Jedis连接池的使用详解
    一.Redis的Java客户端jedis的官方仓库地址:https://github.com/redis/jedisRedis数据结构Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样。1.1引入Redis依赖<dependency><groupId>redis.clients</groupId><artifactId>jedis</......
  • Java 把 Map 的值(Value)转换为 Array, List 或 Set
    概述在这篇短文中,我们将会展示如何把Map中的值取出来,转换为一个Array,、List或者一个Set。 当然,你可以使用JavaJDK来进行转换,你也可以使用Guava来进行转换。 首先,让我们来看看,如何使用原生的JavaJDK把一个Map的值换行为Array。@TestpublicfinalvoidgivenU......
  • Java 把 Map 的值(Value)转换为 Array, List 或 Set
    概述在这篇短文中,我们将会展示如何把Map中的值取出来,转换为一个Array,、List或者一个Set。 当然,你可以使用JavaJDK来进行转换,你也可以使用Guava来进行转换。 首先,让我们来看看,如何使用原生的JavaJDK把一个Map的值换行为Array。@Testpublicfinal......
  • 理解 Java8 的时间API(一)时区
    理解Java8的时间API:java.time由于Java的时间API:java.util.Date、java.util.Calendar、java.util.TimeZone使用起来非常混乱,因此Java8重新设计了一套时间API,放在java.time.*包下。如果需要熟练使用新的LocalDateTime,LocalDate,LocalTime类,最好是先了解时区的概念。因此本文先......
  • Python 设计模式详解
    一、创建型模式1、工厂方法 Factory工厂方法是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型制造业是一个国家工业经济发展的重要支柱,而工厂则是其根基所在。程序设计中的工厂类往往是对对象构造、实例化、初始化过程的封装,而工厂方法则可以升......
  • Java开发 - 读写分离初体验
    前言上一篇中,我们介绍了主从复制,相信学过的小伙伴已经能够很好的掌握主从复制的技术,实际上也并没有那么难,虽然没有讲一主多从,多主多从的配置,但是从一主一从的配置中也很容易联想到该怎么配置,你没猜错,就是你想的那样。这篇博客,我们要讲解的东西是主从复制的应用——读写分离。一般来......