首页 > 其他分享 >设计模式之模板模式和策略模式-----------超级超级详细!超级全面!

设计模式之模板模式和策略模式-----------超级超级详细!超级全面!

时间:2024-08-31 20:50:08浏览次数:16  
标签:int 子类 超级 模式 算法 设计模式 方法 模板

1.模板模式的定义

一个抽象类,公开定义了执行自己的方法/模板。它的子类可以按需重写方法实现,但调用需要按照抽象类中的定义的方式/模板进行。这种类型的设计模式属于行为性模式之一。用于定义一个操作中的算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

注意:

(行为者模式属于设计模式的大类,就像小米手机是属于手机类的这种映射关系,设计模式分为三大类,创建者模式、结构性模式、行为性模式,每个类各有细致的划分,这里不再表述,会在后续专栏中更新!模板模式就是行为性模式之一)。

话不多说,了解基础后,开始学习!come on bro!这里我先给你们打个预防针,它和下面还会讲到另一个行为性模式之一的策略模式很相似,但是实则大差特差,所以我才会选择将它们两个合为一篇文章去总结。

2.模板模式的组成

模板模式主要由抽象模板(Abstract Template)角色具体模板(Concrete Template)角色组成。

抽象模板:定义了一个或多个抽象方法,以便让子类去实现,这些抽象方法叫做基本操作,它们是一个顶级逻辑的组成步骤,然后再定并且实现了一个模板方法,这个模板方法是一般是一个具体方法,是一个顶级逻辑的骨架,而逻辑的组成步骤就是抽象方法,然后抽象方法是由子类去实现。顶级逻辑也有可能调用一些方法。

具体模板:就是继承抽象模板,实现抽象模板类中的抽象方法,具体模板可以有多个,应对不同的实现,从而使顶级逻辑的实现各不相同。

3.模板模式代码

示图如下:

示例:

考虑一个制作咖啡和茶的例子。这两个过程的主要步骤是相同的,但某些细节不同。可以使用模板方法模式来设计这两个饮品的制作过程。

// 抽象类,定义模板方法和抽象方法
abstract class CaffeineBeverage {
    // 模板方法,这里使用了final关键字,是因为不允许子类去修改逻辑骨架
    final void prepareRecipe() {
        brew();
        addCondiments();
    }

    // 抽象方法,由子类实现
    abstract void brew();
    abstract void addCondiments();


}

// 具体子类,实现抽象方法
class Tea extends CaffeineBeverage {
    void brew() {
        System.out.println("Steeping the tea");
    }

    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

class Coffee extends CaffeineBeverage {
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }

}

// 客户端代码
public class TemplateMethodExample {
    public static void main(String[] args) {
        CaffeineBeverage tea = new Tea();
        tea.prepareRecipe();

        System.out.println("-----");

        CaffeineBeverage coffee = new Coffee();
        coffee.prepareRecipe();
    }
}

模板方法模式的结构

模板方法模式通常包括以下几个部分:

  1. 抽象类 (Abstract Class) / 抽象模板

    • 定义了算法的骨架(模板方法)。
    • 包含一个或多个抽象方法,这些方法将在子类中实现。
    • 可以包含一些具体的方法,这些方法是算法的一部分,但不需要在子类中修改。
  2. 具体子类 (Concrete Class) / 具体模板

    • 实现了抽象类中的抽象方法,以提供算法的具体步骤。
    • 子类可以根据需要重写抽象类中的某些步骤,但算法的整体结构仍由抽象类控制。

看完总结现在是不是恍然大悟啦!接下来我要继续讲解策略模式了。

4.策略模式的定义

策略模式也是行为性模式之一,其用意是针对一组算法,将每一个算法封装到具有共同性质的接口中,从而使这组算法相互替换。其主要目的就是替换if/else语句写法,并且可以随时替换。替换if/else语句的方法还有一种是利用枚举类,这里就当做扩展,想要了解,可以关注我,这几天我会尽快总结!谢谢关注!

5.策略模式的组成

策略模式主要有三个角色组成:环境角色(Context)抽象策略角色(Strategy)具体策略角色(ConcreteStrategy)

环境角色:持有一个策略的引用,提供给客户端使用的类。

抽象策略角色:是一个抽象角色,通常由抽象或者接口实现,此角色给出所有具体策略类所需要的接口,这里其实使用接口的形式,因为java中类只能单一继承,不能多继承,所以使用接口,因为接口可以多继承,这样子类就具有优秀的拓展性。

具体策略角色:实现抽象策略类的方法。

示例图如下:

6.策略模式的代码

以计算器为例,如果我们想得到两个数字相加的和,我们需要用到"+"符号,得到相减的差,需要用到"-"符号等等。
虽然我们可以通过字符串比较使用if/else写成通用方法,但是计算的符号每次增加,我们就不得不加在原先的方法中进行增加相应的代码,如果后续计算方法增加、修改或删除,那么会使后续的维护变得困难。
但是在这些方法中,我们发现其基本方法是固定的,这时我们就可以通过策略模式来进行开发,可以有效避免通过if/else来进行判断,即使后续增加其他的计算规则也可灵活进行调整。
首先定义一个抽象策略角色,并拥有一个计算的方法。

interface CalculateStrategy {
    int doOperation(int num1, int num2);
}

然后再定义加减乘除这些具体策略角色并实现方法,代码如下:

class OperationAdd implements CalculateStrategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

class OperationSub implements CalculateStrategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

class OperationMul implements CalculateStrategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

class OperationDiv implements CalculateStrategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 / num2;
    }
}

再定一个环境角色,为客户端提供方法:

class calulatorContext {
    private CalulateStrategy strategy;
    
    public CalulatorContext(CalulateStrategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1, num2);
    }
}

测试代码如下:

 策略模式优点:

  • 扩展性好,同一种类算法,直接添加新的类。
  • 灵活性好,可以对算法进行切换。

缺点:

  • 如果策略过多,会增加系统复杂性。
  • 客户端需要知道所有具体策略类才能进行调用。

到现在全都讲完啦,现在要开始对比两种行为型模式的区别

模板方法模式(Template Method Pattern)和策略模式(Strategy Pattern)都是行为型设计模式,它们确实在某些方面有相似之处,但本质上解决的问题和使用场景有所不同。下面将详细比较这两种模式的相似点和区别,并通过示例进一步说明。

相似点

  1. 封装变化

    • 两者都通过封装算法的不同部分来实现灵活性,允许在不改变整体结构的情况下改变部分行为。
  2. 提高代码复用性

    • 都旨在通过抽象化和模块化来提高代码的复用性,减少重复代码。
  3. 依赖抽象而非具体实现

    • 两种模式都依赖于抽象(如接口或抽象类),而不是具体的实现类,从而实现松耦合。

区别

  1. 控制反转的方向

    • 模板方法模式:控制权在抽象类中。抽象类定义了算法的骨架,具体步骤由子类实现。子类在父类的控制下实现特定步骤。
    • 策略模式:控制权在客户端。客户端选择并切换不同的策略(算法),策略独立于使用它的上下文。
  2. 继承 vs 组合

    • 模板方法模式:依赖继承关系。子类通过继承抽象类来定制算法的某些步骤。
    • 策略模式:依赖组合关系。上下文类持有策略对象,通过组合而不是继承来改变行为。
  3. 算法结构

    • 模板方法模式:适用于算法步骤固定,但某些步骤可以变化的场景。整体算法结构由抽象类控制。
    • 策略模式:适用于多个算法可以互换的场景。不同策略可以在运行时动态切换。
  4. 灵活性

    • 策略模式:更加灵活,因为策略可以在运行时自由切换,不依赖继承层次结构。
    • 模板方法模式:灵活性较低,因为需要通过继承来扩展,且固定的算法结构可能限制了变化。

 

标签:int,子类,超级,模式,算法,设计模式,方法,模板
From: https://blog.csdn.net/qq_36556126/article/details/141756886

相关文章

  • Java设计模式之单例模式(Singleton)
    单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。这样的模式有几个好处:某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。省去了new操作符,降低了系统内存的使用频率,减轻GC压力。有些类如交易所的核心交易引擎......
  • (大三上_游戏开发设计模式_上课_1)多态练习_计算机
    灵活性,可扩展,灵活性,可维护封装继承:要有基类代码片段写整个属性    基类里面 基态      基方向,虚方法//虚方法,可以写在实例方法里 publicvirtualdoubleGetResult() {  return0;}实例方法,可以创建实例抽象方法,要写在抽......
  • 模板方法模式:如何实现同一模板框架下的算法扩展?
    模板方法模式的原理和代码实现都比较简单,在软件开发中也被广泛应用,但是因为使用继承机制,副作用往往盖过了主要作用,所以在使用时尤其要小心谨慎。一、模式原理分析模板方法模式原始定义是:在操作中定义算法的框架,将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的......
  • 第七章 项目布局实现(7.4.6)——暗黑模式切换功能
    7.4.6暗黑模式切换功能ElementPlus参考:https://cn.element-plus.org/zh-CN/guide/dark-mode.htmlVueU参考:https://vueuse.org/core/useDark/ElementPlus2.2.0+版本支持暗黑模式,导入暗黑样式文件,然后在index.html的html标签上添加一个class="dark"的类名即可......
  • 设计模式 -- 代理模式(Proxy Pattern)
    基本介绍代理模式:为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象代理模式有不......
  • 设计模式 -- 享元模式(Flyweight Pattern)
    1问题引出        小型的外包项目,给客户A做一个产品展示网站,客户A的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同:有客户要求以新闻的形式发布有客户人要求以博客的形式发布有客户希望以微信公众号的形式发布直接复制粘贴一份,然后根据......
  • 【Java设计模式】委托模式:掌握高效任务分配
    文章目录【Java设计模式】委托模式:掌握高效任务分配一、概述二、详细解释及实际示例三、Java中委托模式的编程示例四、何时在Java中使用委托模式五、委托模式在Java中的实际应用六、委托模式的优点和权衡七、源码下载【Java设计模式】委托模式:掌握高效任务分配一、......
  • 【Java设计模式】组件模式:使用可复用组件简化复杂系统
    文章目录【Java设计模式】组件模式:使用可复用组件简化复杂系统一、概述二、组件设计模式的别名三、组件设计模式的意图四、组件模式的详细解释及实际示例五、Java中组件模式的编程示例六、何时在Java中使用组件模式七、组件模式在Java中的实际应用八、组件模式的优点和权......
  • 一个操作系统的设计与实现——第19章 IA32-e模式
    19.164位段描述符与GDT在32位操作系统中,我们使用的是平坦模型而非分段模型,从而,段描述符的段基址和段限长均成了摆设。在64位模式下,就连CPU也淘汰了分段模型,转而固定使用平坦模型。64位代码段描述符如下图所示:如图所示,由于固定使用平坦模型,段描述符中的段基址、段限长、粒度等......