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
目录
相关文章
|
7天前
|
安全 Java API
Java 17新特性让你的代码起飞!
【10月更文挑战第4天】自Java 8发布以来,Java语言经历了多次重大更新,每一次都引入了令人兴奋的新特性,极大地提升了开发效率和代码质量。本文将带你从Java 8一路走到Java 17,探索那些能让你的代码起飞的关键特性。
32 1
|
6天前
|
Java 程序员 API
Java中的Lambda表达式:简化代码的秘密武器
【10月更文挑战第11天】 在Java编程中,Lambda表达式是一种简洁而强大的工具,它允许我们将函数作为参数传递给其他方法。本文将介绍Lambda表达式的基本概念、使用方法以及在实际项目中的应用案例,帮助你更好地理解和利用这一特性来简化代码。
20 8
|
4天前
|
Java 开发者
在Java编程中,正确的命名规范不仅能提升代码的可读性和可维护性,还能有效避免命名冲突。
【10月更文挑战第13天】在Java编程中,正确的命名规范不仅能提升代码的可读性和可维护性,还能有效避免命名冲突。本文将带你深入了解Java命名规则,包括标识符的基本规则、变量和方法的命名方式、常量的命名习惯以及如何避免关键字冲突,通过实例解析,助你写出更规范、优雅的代码。
25 3
|
4天前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
11 3
|
4天前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。
|
4天前
|
Java Apache Maven
Java将word文档转换成pdf文件的方法?
【10月更文挑战第13天】Java将word文档转换成pdf文件的方法?
12 1
|
8天前
|
Java 编译器
Java“返回类型为 void 的方法不能返回一个值”解决
在 Java 中,如果一个方法的返回类型被声明为 void,那么该方法不应该包含返回值的语句。如果尝试从这样的方法中返回一个值,编译器将报错。解决办法是移除返回值语句或更改方法的返回类型。
|
8天前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
14 1
|
8天前
|
Java
让星星⭐月亮告诉你,Java synchronized(*.class) synchronized 方法 synchronized(this)分析
本文通过Java代码示例,介绍了`synchronized`关键字在类和实例方法上的使用。总结了三种情况:1) 类级别的锁,多个实例对象在同一时刻只能有一个获取锁;2) 实例方法级别的锁,多个实例对象可以同时执行;3) 同一实例对象的多个线程,同一时刻只能有一个线程执行同步方法。
9 1
|
7天前
|
Java 编译器 API
从Java 8到Java 17,这些新特性让你的代码起飞!
【10月更文挑战第10天】在软件开发领域,Java作为一种历史悠久且广泛使用的编程语言,不断进化以适应新的需求和挑战。从Java 8到Java 17,每一次版本更新都带来了诸多新特性和改进,极大地提升了开发效率和代码质量。今天,我们就来一起探讨这些新特性,看看它们是如何让我们的代码“起飞”的。
69 0