JAVA模板方法设计模式——Java设计模式,写漂亮的代码——

简介: Java设计模式,写漂亮的代码————模板方法设计模式简介:模板方法设计模式是Java设计模式中很简单、应用非常广泛的的一种设计模式,该模式体现了编程的抽象思想(抽象是所有子类的共性封装),仅仅使用了Java的继承机制。

Java设计模式,写漂亮的代码

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


简介:

模板方法设计模式是Java设计模式中很简单、应用非常广泛的的一种设计模式,该模式体现了编程的抽象思想(抽象是所有子类的共性封装),
仅仅使用了Java的继承机制。其实很可能在你写代码的过程中已经使用过了很多次这种模式,只是你还不太清楚那就是模板方法设计模式。
接下来就让我们一起去看看,到底什么是模板方法设计模式呢?

首先看一下描述:

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

UML类图描述:

下图就是模板方法设计模式的UML类图描述,正如你所见,没错,就是这么简单,一目就能了然。

img_3d820d4172f38ae5dc3d4b60aa826855.png
模板方法模式UML类图

其中AbstractClass叫做抽象模板类,实现了模板方法,定义了算法的骨架,它的方法分为两类:

  1. 基本方法:基本方法也叫作基本操作,是由子类实现的方法,并且在模板方法被调用.
  2. 模板方法:可以有一个或者几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。
    具体类:ConcreteClass:实现抽象类中的抽象方法,完成完整的算法。

下面通过一个简单的例子描述下模板方法模式的应用:

本例子通过模拟手机情景模式的过程,简单描述下模板方法的应用:

public abstract class SceneMode {
    //这里定义了一个抽象类,即模板方法模式的抽象模板类,把子类共有的一些操作抽象到该类中,情景模式普遍就是响铃和震动的操作,这里将通用的流程放到该类中,具体的配置通过其子类来完成
    private static final String TAG = "SceneMode";
    private static final String DEFAULT_RING = "little Star";
    private String mRing = DEFAULT_RING;
    private boolean isRing;
    private boolean isVibrating;
    public void goModel() {
       Log.d(TAG, "开启模式:");
    }
    //共性方法的抽象,由子类去实现具体的情景模式名称
    public abstract String getSceneModelName();

    public abstract boolean isRing();

    public abstract boolean isVibration();

    //钩子函数,外界条件改变,影响了模板函数的执行
    public void setRingMusic(String ringName) {
        this.mRing = ringName;
    };

    private void playRing() {
        this.isRing = true;
        Log.d(TAG, "play: " + mRing);
    }

    private void vibrating() {
        this.isVibrating = true;
        Log.d(TAG, "vibrating");
    }

    private void startRing() {
        if (isRing()) playRing();
    }

    private void startVibrating() {
        if (isVibration()) vibrating();
    }

    private void stopRing() {
        if (isRing) {
            Log.d(TAG, "停止响铃");
            this.isRing = false;
        }
    }

    private void stopVibration() {
        if (isVibrating) {
            Log.d(TAG, "停止震动");
            this.isVibrating = false;
        }
    }

    public final void called() {
        //为了防止恶意的操作,一般模板方法都加上final关键字,不允许被重写
        Log.d(TAG, "called: 被呼叫");
        new Thread() {
            @Override
            public void run() {
                startRing();
                startVibrating();
                try {
                    Thread.sleep(60 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                stopRing();
                stopVibration();
            }
        }.start();
    }
}

public class RingSceneMode extends SceneMode{
    //子类响铃模式,完成对应的配置,达到重定义父类called的动作
    @Override
    public String getSceneModelName() {
        return "响铃模式";
    }

    @Override
    public boolean isRing() {
        return true;
    }

    @Override
    public boolean isVibration() {
        return false;
    }
}

public class VibrationSceneMode extends SceneMode{
  //子类震动模式,完成对应的配置,达到重定义父类called的动作
    @Override
    public String getSceneModelName() {
        return "振动模式";
    }

    @Override
    public boolean isRing() {
        return false;
    }

    @Override
    public boolean isVibration() {
        return true;
    }
}

如下为场景类,创建不同的模式来完成对应的模式匹配,实现特定模式达到的效果
        //1.设置RingMode
        mSceneMode = new RingSceneMode();
        mSceneMode.setRingMusic("lemon tree");
        Log.d(TAG, mSceneMode.getSceneModelName());
        mSceneMode.called();

        //2.设置VibrationMode
        mSceneMode = new VibrationSceneMode();
        Log.d(TAG, mSceneMode.getSceneModelName());
        mSceneMode.called();

        //3.设置Ring + Vibration Mode
        mSceneMode = new RingAndVibrationSceneMode();
        mSceneMode.setRingMusic("lemon tree");
        Log.d(TAG, mSceneMode.getSceneModelName());
        mSceneMode.called();

模板方法模式的优点:

  1. 封装不变部分,扩展可变部分;
  2. 提取公共部分代码,便于维护;
  3. 行为由父类控制,子类实现。

模板方法模式的使用场景

  1. 多个子类有公有的方法,并且逻辑基本相同时。
  2. 重要复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则有各个子类实现。
  3. 重构时, 模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(外界条件改变,影响到模板方法的执行)约束其行为。
    参考Github地址:https://github.com/tomato0/TempalatePatterns/tree/master
    CSDN:http://blog.csdn.net/wsq_tomato/article/details/79518729
目录
相关文章
|
2天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
2天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
2天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
3天前
|
SQL JavaScript 前端开发
基于Java访问Hive的JUnit5测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Java、来开发Hive应用的方法,产生的代码如下
20 6
|
10天前
|
存储 Java 开发者
【Java新纪元启航】JDK 22:解锁未命名变量与模式,让代码更简洁,思维更自由!
【9月更文挑战第7天】JDK 22带来的未命名变量与模式匹配的结合,是Java编程语言发展历程中的一个重要里程碑。它不仅简化了代码,提高了开发效率,更重要的是,它激发了我们对Java编程的新思考,让我们有机会以更加自由、更加创造性的方式解决问题。随着Java生态系统的不断演进,我们有理由相信,未来的Java将更加灵活、更加强大,为开发者们提供更加广阔的舞台。让我们携手并进,共同迎接Java新纪元的到来!
35 11
|
2天前
|
Java 开发者
探索Java中的Lambda表达式:简化代码,提升效率
【9月更文挑战第14天】本文旨在揭示Java 8中引入的Lambda表达式如何革新了我们编写和管理代码的方式。通过简洁明了的语言和直观的代码示例,我们将一起走进Lambda表达式的世界,了解其基本概念、语法结构以及在实际编程中的应用。文章不仅会展示Lambda表达式的魅力所在,还会指导读者如何在日常工作中有效利用这一特性,以提高编码效率和程序可读性。
|
5天前
|
Java
Java的方法详解
Java的方法是类中的重要组成部分,用于定义类的行为。方法可以接收参数、执行操作并返回结果。其基本语法包括返回类型、方法名、参数列表和方法体。方法支持重载,即同名但参数不同的多个方法;静态方法则直接通过类名调用,无需实例化。此外,Java还支持可变参数,允许方法接收不定数量的参数。通过访问修饰符如`public`、`protected`、`private`,可以控制方法的可见性。方法是实现类功能的基本单元,增强了程序的灵活性和复用性。
|
8天前
|
并行计算 Java 开发者
探索Java中的Lambda表达式:简化代码,提升效率
Lambda表达式在Java 8中引入,旨在简化集合操作和并行计算。本文将通过浅显易懂的语言,带你了解Lambda表达式的基本概念、语法结构,并通过实例展示如何在Java项目中应用Lambda表达式来优化代码,提高开发效率。我们将一起探讨这一现代编程工具如何改变我们的Java编码方式,并思考它对程序设计哲学的影响。
|
8天前
|
安全 Java 测试技术
掌握Java的并发编程:解锁高效代码的秘密
在Java的世界里,并发编程就像是一场精妙的舞蹈,需要精准的步伐和和谐的节奏。本文将带你走进Java并发的世界,从基础概念到高级技巧,一步步揭示如何编写高效、稳定的并发代码。让我们一起探索线程池的奥秘、同步机制的智慧,以及避免常见陷阱的策略。
|
3天前
|
JavaScript 前端开发 Java
通过JUnit5访问Java静态、私有、保护变量和方法
在《通过Gtest访问C++静态、私有、保护变量和方法》一文中介绍了如何通过Gtest访问C++静态、私有、保护变量和方法,本文介绍如何通过Junit5访问Java静态、私有、保护变量和方法。
11 0