当前位置: 首页 > news >正文

模版与策略模式

一,怎么选择

如果需要固定的执行流程,选模版

如果不需要固定的执行流程,只需要对一个方法做具体抽象,选策略

参考文章:

常用设计模式汇总,告诉你如何学习设计模式

二,常用写法

子类 extends absClass implements businiessInterface

absClass = absClass impements strategyInterface

样例与详细分析

public class ECCBMS195ServiceImpl extends AbstractBmsService implements ECCBMS195Service {
public abstract class AbstractBmsService implements BmsService {

一,策略接口

方法1:抽象类实现
方法2:子类实现,标识策略对象。后续工厂模式有用

public interface strategyInterface {boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception;BmsServiceEnum getType();
}

二,抽象类

absClass

@Override
@Transactional
public boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception {this.process(eccMessageReqVO);return true;
}public abstract void process(EccMessageReqVO eccMessageReqVO) throws Exception;

三,业务接口 businiessInterface

public interface EccBms111Service {void bms111Execute(ReqEccBms111VO reqEccBms110VO) throws Exception;}

四,子类

1,实现业务接口逻辑businiessInterface

public void bms111Execute(ReqEccBms111VO reqEccBms111VO) throws Exception {}

2,实现抽象方法 process。且抽象接口中,调用具体业务接口

public void process(EccMessageReqVO eccMessageReqVO) throws Exception {this.bms111Execute(reqEccBms111VO);}

3,实现枚举接口,标识自身策略对象类型

@Override
public BmsServiceEnum getType() {return BmsServiceEnum.ECC_BMS111;
}

5,工厂模式

初始化对象,提供获取具体对象接口

@Component
public class BmsServiceSelector implements InitializingBean {private static final Map<BmsServiceEnum, BmsService> serviceMap = new HashMap<>();@Resourceprivate List<BmsService> EccServices;@Overridepublic void afterPropertiesSet() throws Exception {for (BmsService service : EccServices) {serviceMap.put(service.getType(), service);}}public BmsService getService(BmsServiceEnum bmsServiceEnum) {if (null == bmsServiceEnum){throw new IllegalArgumentException("操作失败!");}return serviceMap.get(bmsServiceEnum);}
}

6,调用方

1,首先调用者,不同业务场景有自己的唯一标识,比如MQ下发时,不同的场景,MQ tag不同

根据tag - > 获取枚举 -》根据枚举 -〉 获取具体对象 - 》 用具体对象调用具体逻辑

2,调用执行逻辑是策略接口中方法,execute,这个接口有抽象类实现(非子类实现)

public interface BmsService {boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception;BmsServiceEnum getType();}
BmsServiceEnum bmsServiceEnum = BmsServiceEnum.fromValue(vo.getTags());
BmsService bmsService = bmsServiceSelector.getService(bmsServiceEnum);
if(Objects.isNull(bmsService)) return true;
vo.setEccServiceName(bmsServiceEnum.getName());
bmsService.execute(vo);

 疑问:如果不在BmsService中定义,删除,直接在抽象类中写个,普通的方法execute(即模版方法),有问题吗?

你看下有问题吗,报错了。调用者获取的是策略接口对象BmsService,是这个接口调用的。

再次体现,针对接口编程,非实现类编程。

 为什么有此一问呢?是不是想到了文章中这里,策略模式中定义Context,里面定义了抽象类,

private penguin _penguin;

然后直接根据抽象类对象,调用抽象类中抽象接口与普通接口。

违背了设计原则:依赖接口,非依赖具体类。

public class behaviorContext {private penguin _penguin;public behaviorContext(penguin newPenguin) {_penguin = newPenguin;}public void setPenguin(penguin newPenguin) {_penguin = newPenguin;}public void everyDay() {_penguin.eating();_penguin.sleeping();_penguin.beating();}
}

 实际使用中,会这样用吗,依赖抽象类。见过如下

场景:不同业务场景,导入excel,读取excel数据,并返回不同场景的对象(用通配符T)

public class BatchVehicleInfoController {private final ExcelUploadDataService<VehicleCoreExcel> vehicleCoreDataExcelService;
}
public abstract class ExcelUploadDataService<T> {/*** excel 读取含表头** @param excelInputStream* @return*/public ExcelReadResult<T> readWithHead(final InputStream excelInputStream, final Class<T> clazz) {}}

三,这一波下来用了什么设计模式

哪一波?上文【常用写法】

子类 extends absClass implements businiessInterface

absClass = absClass impements strategyInterface

模版

抽象类中定义了模版方法execute(只有一个行为process),模版方法中,调用了抽象接口 process。

抽象类 + 模版方法 + 抽象接口(子类实现),根据这三点可以理解为模版模式

public boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception { this.process(eccMessageReqVO); return true; }

策略

抽象类 + 抽象接口,可以理解为策略模式。这也是策略的一般格式。

二者异同

好像与模版模式,一样,那最大的不同是什么

我认为是调用者,获取对象的方式不同

模版模式,每一个场景对象直接new的。参考这篇文档

常用设计模式汇总,告诉你如何学习设计模式

如下

public class test {public static void main(String[] args) {System.out.println("littlePenguin:");littlePenguin penguin1 = new littlePenguin();penguin1.everyDay();System.out.println("middlePenguin:");middlePenguin penguin2 = new middlePenguin();penguin2.everyDay();System.out.println("bigPenguin:");bigPenguin penguin3 = new bigPenguin();penguin3.everyDay();}
}

模版模式,优化了调用者对象的创建方式

文章描述如下

这里就是策略模式的重点,我们再看一下策略模式的定义“我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象”,那么该contex对象如下:

public class behaviorContext {private penguin _penguin;public behaviorContext(penguin newPenguin) {_penguin = newPenguin;}public void setPenguin(penguin newPenguin) {_penguin = newPenguin;}public void everyDay() {_penguin.eating();_penguin.sleeping();_penguin.beating();}
}

最后看调用方式:

public class test {public static void main(String[] args) {behaviorContext behavior = new behaviorContext(new littlePenguin());behavior.everyDay();behavior.setPenguin(new middlePenguin());behavior.everyDay();behavior.setPenguin(new bigPenguin());behavior.everyDay();}
}

有何感想: 上面强调了两个对象

策略的对象 + context对象

你看最后调用的时候,还是new了,对应和模版模式相同。

只是包了一层,方法的真正的调用者不同

模版:new的具体对象直接调用

    littlePenguin penguin1 = new littlePenguin();
        penguin1.everyDay();

策略:抽象对象调用

把调用者对象包了一下,且这个对象是一个抽象的

private penguin _penguin;

调用者还是对象,是不过这个对象不是new的具体对象,是一个抽象对象

这也体现了设计原则:针对接口编程,不要针对实现编程

    public void everyDay() {_penguin.eating();_penguin.sleeping();_penguin.beating();}

那context对象的作用是什么?

再看下概念:一个行为随着策略对象改变而改变的context对象

总体来看,还是创建对象,并封装了一个调用具体逻辑的方法

public void everyDay() {_penguin.eating();_penguin.sleeping();_penguin.beating();}

但是我觉得封装方法不是重点,封装的方法,可以看作就一个抽象方法 _penguin.beating();

它的作用还是,提供了一个创建对象的入口。

一句话,它做的工厂模式的事

工厂

上面第三点,完全体现了,工厂模式

四,总结

现在回头看,模版与策略主要区别

1,模版有一套固定行为,策略无

2,策略封装了,对象的创建与获取。像是一个不那么完整的工厂模式(对比上面第5点)

相关文章:

模版与策略模式

一&#xff0c;怎么选择 如果需要固定的执行流程&#xff0c;选模版 如果不需要固定的执行流程&#xff0c;只需要对一个方法做具体抽象&#xff0c;选策略 参考文章&#xff1a; 常用设计模式汇总&#xff0c;告诉你如何学习设计模式 二&#xff0c;常用写法 子类 exten…...

SQL-Python

师从黑马程序员 数据库介绍 数据库就是存储数据的库 数据组织&#xff1a;库->表->数据 数据库和SQL的关系 MySQL的基础命令 SQL基础 SQL语言的分类 SQL的语法特征 DDL-库管理 show DATABASES;use sys;SELECT database();CREATE DATABASE test CHARSET utf-8;SHOW D…...

mysql索引以及优化

索引的作用 在数据库表中对字段建立索引可以大大提高查询速度 mysql索引类型 普通索引唯一索引&#xff1a; 唯一索引列的值必须唯一允许有空值&#xff0c;如果是组合索引&#xff0c;则列值的组合必须唯一create unique index indexName on mytable(username(length))修改表结…...

【pytorch06】 维度变换

常用API view/reshapesqueeze/unsqueezetranspose/t/permuteexpand/repeat view和reshape view操作的基本前提是保证numel()一致 a.view(4,28*28)的物理意义是把行宽以及通道合并在一起&#xff0c;对于4张图片&#xff0c;我们直接把所有数据都合在一起&#xff0c;用一个7…...

移动Web开发实战内容要点!!!

移动web开发 目录 移动web开发 第一章、Web开发标准与网页网站制作介绍 1.1Web开发标准 1.2网页基本构成元素 第二章、Web开发技术基础 2.1HTML的主要特点&#xff1a; 2.2HTML基本知识 2.3CSS样式 2.4JavaScript 第三章、打造移动Web应用程序 3.1为什么Android会成…...

spdlog生产者消费者模式

spdlog生产者消费者模式 spdlog提供了异步模式&#xff0c;显示的创建async_logger, 配合环形队列实现的消息队列和线程池实现了异步模式。异步logger提交日志信息和自身指针&#xff0c; 任务线程从消息队列中取出消息后执行对应的sink和flush动作。 1. 环形队列 1.1 环形队…...

日语 13 14

13. スピーチの依頼 いらい 自信 自信 自信 自信 自信 じしん 折り入って 折り入って 折り入って おりいって  诚恳 頼み 頼み 頼み 頼み 頼み  たのみ 请求 整備 整備 整備 整備 整備 せいび 维修 肥満 肥満 肥満 肥満 肥満 ひまん 肥胖 権利 …...

初学者应该掌握的MySQL数据库的基本组成部分及概念

MySQL数据库作为一种开源的关系型数据库管理系统&#xff0c;被广泛应用于Web应用开发和数据存储。它具有高性能、易用性和可靠性等特点&#xff0c;是开发者们的首选之一。在本篇文章中&#xff0c;我们将详细介绍MySQL数据库的核心组成部分&#xff0c;帮助你深入理解这个强大…...

四川汇聚荣科技有限公司怎么样?

在探讨一家科技公司的综合实力时&#xff0c;我们往往从多个维度进行考量&#xff0c;包括但不限于公司的发展历程、产品与服务的质量、市场表现、技术创新能力以及企业文化。四川汇聚荣科技有限公司作为一家位于中国西部的科技企业&#xff0c;其表现和影响力自然也受到业界和…...

数据仓库和数据库有什么区别?

一、什么是数据仓库二、什么是数据库三、数据仓库和数据库有什么区别 一、什么是数据仓库 数据仓库&#xff08;Data Warehouse&#xff09;是一种专门用于存储和管理大量结构化数据的信息系统。它通过整合来自不同来源的数据&#xff0c;为企业提供统一、一致的数据视图&…...

计算子网掩码

例题 如果子网掩码是255.255.192.0&#xff0c; 那么下面主机&#xff08;&#xff09;必须通过路由器才能与主机129.23.144.16通信&#xff08; 1分 &#xff09;A.129.23.148.127B. 129.23.191.21C. 129.23.127.222D. 129.23.130.33计算 要确定哪些主机必须通过路由器才能与…...

JVM 垃圾收集算法

首先我们要知晓&#xff0c;垃圾收集是建立在两个分代假说之上的&#xff1a; ①弱分代假说&#xff1a;绝大多数对象都是朝生夕灭的 ②强分代假说&#xff1a;熬过越多次垃圾收集的对象就越难消亡 收集器应该将Java堆划分出不同的区域&#xff0c;然后将回收对象依据其年龄分配…...

安装虚拟环境

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Flask依赖两个外部库&#xff1a;Werkzeug和Jinja2。Werkzeug是一个WSGI&#xff08;在Web应用和多种服务器之间的标准 Python 接口&#xff09;工具…...

【ai】tx2-nx:安装深度学习环境及4.6对应pytorch

参考:https://www.waveshare.net/wiki/Jetson_TX2_NX#AI.E5.85.A5.E9.97.A8 英伟达2021年发布的的tritionserver 2.17 版本中,backend 有tensorflow1 和 onnxruntime ,他们都是做什么用的,作为backend 对于 triton 推理server意义是什么,是否应该有pytorch? Triton Infer…...

华为某员工爆料:三年前985本科起薪30万,现在硕士起薪还是30w,感慨互联网行情变化

“曾经的30万年薪&#xff0c;是985本科学历的‘标配’&#xff0c;如今硕士也只值这个价&#xff1f;” 一位华为员工的爆料&#xff0c;揭开了互联网行业薪资变化的冰山一角&#xff0c;也引发了不少人的焦虑&#xff1a;互联网人才“通货膨胀”的时代&#xff0c;真的结束了…...

Java基础--AOP--1.概述

一、AOP简介 AOP&#xff08;Aspect Oriented &#xff09;即为面向切面编程&#xff0c;也可称为面向方法编程&#xff0c;是方法增强的一种途径&#xff0c;通常可用于记录操作日志、权限空值、事务管理等等;Spring框架中的事务底层就是AOP。 二、AOP的组成 1、连接点&…...

【计算机网络仿真实验-实验3.1、3.2】交换路由综合实验

实验3.1 交换路由综合实验——作业1 一、实验目的 运用实验二&#xff08;可前往博主首页计算机网络专栏下查看&#xff09;中学到的知识&#xff0c;将这个图中的PC机连接起来组网并分析&#xff0c;本篇涉及代码以截图展示&#xff0c;过于简单的代码及操作不再详细介绍&…...

RSA密码系统的特定密钥泄露攻击与Coppersmith方法的应用

PrimiHub一款由密码学专家团队打造的开源隐私计算平台&#xff0c;专注于分享数据安全、密码学、联邦学习、同态加密等隐私计算领域的技术和内容。 RSA密码系统作为当前最广泛使用的公钥加密算法之一&#xff0c;其安全性依赖于大整数分解问题的困难性。然而&#xff0c;随着计…...

从零开始精通Onvif之音视频流传输

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 概述 Onvif协议的核心作用之一&#xff0c;是定义了如何通过网络访问和控制IP摄像机和其他视频设备。Onvif协议不仅涉及设备发现、设备管理&…...

CentOS 7、Debian、Ubuntu,这些是什么意思

CentOS 7、Debian、Ubuntu 都是基于 Linux 内核的操作系统&#xff0c;它们各自有不同的特性和用途。以下是对它们的详细解释&#xff1a; CentOS 7 CentOS&#xff08;Community ENTerprise Operating System&#xff09; 是一个基于开源的 Linux 发行版。CentOS 7 是 CentOS …...

终极指南:如何为Figma安装中文界面插件,让设计工作更高效

终极指南&#xff1a;如何为Figma安装中文界面插件&#xff0c;让设计工作更高效 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN FigmaCN是一款专为中文用户设计的Figma界面汉化插件&am…...

用Multisim 14.0复刻经典:手把手教你搭建一个能校时的数字电子钟(附完整仿真文件)

用Multisim 14.0打造高精度数字电子钟&#xff1a;从原理到仿真的完整实践指南 在数字电路的学习过程中&#xff0c;没有什么比亲手搭建一个功能完整的数字电子钟更能检验学习成果了。这个看似简单的项目实际上涵盖了振荡器、分频器、计数器、译码显示和校时电路等数字电路的核…...

Windows右键菜单终极清理指南:3步让你的右键菜单重获新生

Windows右键菜单终极清理指南&#xff1a;3步让你的右键菜单重获新生 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 还在为每次右键点击文件时弹出的杂乱菜单而…...

Oracle 数据库中的 REF 类型与触发器的使用

在 Oracle 数据库中,引用类型(REF)是对象类型之间关联的一种强大工具。特别是在复杂的企业应用中,REF 类型可以帮助我们建立对象间的引用关系,模拟现实世界的关系模型。本文将通过一个实际的例子,介绍如何在 Oracle 中使用 REF 类型,以及如何通过触发器(Trigger)来确保…...

Qwen3.5-2B轻量模型评测:端侧推理延迟、功耗、准确率三维平衡点实测

Qwen3.5-2B轻量模型评测&#xff1a;端侧推理延迟、功耗、准确率三维平衡点实测 1. 模型概述 Qwen3.5-2B是通义千问团队推出的轻量化多模态基础模型&#xff0c;属于Qwen3.5系列的小参数版本&#xff08;20亿参数&#xff09;。该模型专为低功耗、低门槛部署场景设计&#xf…...

电子工程师必看:MOS管、三极管、IGBT选型指南(附实际电路设计案例)

电子工程师必看&#xff1a;MOS管、三极管、IGBT选型指南&#xff08;附实际电路设计案例&#xff09; 在电子设计的世界里&#xff0c;选择合适的功率开关器件往往决定着整个电路的成败。作为一名电子工程师&#xff0c;我曾在多个项目中因为选型不当而付出惨痛代价——从简单…...

mT5分类增强版中文-base效果惊艳:同一输入生成‘正式/口语/幽默’三风格文本示例

mT5分类增强版中文-base效果惊艳&#xff1a;同一输入生成‘正式/口语/幽默’三风格文本示例 1. 模型介绍&#xff1a;零样本学习的文本增强利器 mT5分类增强版中文-base是一个基于mT5架构的文本增强模型&#xff0c;专门针对中文场景进行了深度优化。这个模型最大的特点是采…...

手把手教你用STM32的ADC读取PT100模块,实现高精度温度采集(附完整代码)

基于STM32的PT100高精度温度采集系统设计与实现 在工业控制和精密测量领域&#xff0c;温度监测的准确性往往直接影响产品质量和生产安全。PT100作为最常用的温度传感器之一&#xff0c;凭借其优异的线性度和稳定性&#xff0c;成为众多工程师的首选。本文将深入探讨如何利用ST…...

手机网站建设:新手指南,一步到位打造完美移动版网站 关键词: 手机网站建设, 移动网站设计, 响应式设计, SEO优化, 用户体验

...

别再让MATLAB并行池浪费你的内存!保姆级教程教你手动精准管理Parallel Pool

MATLAB并行池内存优化实战&#xff1a;从自动管理到精准控制 在科学计算和工程仿真领域&#xff0c;MATLAB的Parallel Computing Toolbox无疑是提升运算效率的利器。但许多资深用户都曾经历过这样的困扰&#xff1a;完成大规模并行计算后&#xff0c;发现系统内存依然被并行池占…...