详述java的设计模式(三)
1.装饰者模式
装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
使用场景:
-
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
-
需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
示例:
interface Coffee {double getCost();String getIngredients();
}class SimpleCoffee implements Coffee {@Overridepublic double getCost() {return 1;}@Overridepublic String getIngredients() {return "Coffee";}
}abstract class CoffeeDecorator implements Coffee {private final Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}@Overridepublic double getCost() {return decoratedCoffee.getCost();}@Overridepublic String getIngredients() {return decoratedCoffee.getIngredients();}
}class MilkCoffee extends CoffeeDecorator {public MilkCoffee(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 0.5;}@Overridepublic String getIngredients() {return super.getIngredients() + ", Milk";}
}class WhipCoffee extends CoffeeDecorator {public WhipCoffee(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 0.7;}@Overridepublic String getIngredients() {return super.getIngredients() + ", Whip";}
}public class DecoratorExample {public static void main(String[] args) {Coffee c = new SimpleCoffee();System.out.println("Cost : " + c.getCost() + "; Ingredients : " + c.getIngredients());c = new MilkCoffee(c);System.out.println("Cost : " + c.getCost() + "; Ingredients : " + c.getIngredients());c = new WhipCoffee(c);System.out.println("Cost : " + c.getCost() + "; Ingredients : " + c.getIngredients());}
}
该示例演示了一个简单的咖啡饮料店,其中定义了一个抽象接口Coffee,该接口有两个方法:getCost()和getIngredients()。
然后我们定义了一个简单的咖啡饮料:SimpleCoffee,它实现了Coffee接口,并且有默认的价格和成分。
优缺点
优点
-
装饰者模式可以提供比继承更多的灵活性
-
可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
-
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
-
具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
缺点
-
会产生很多的小对象,增加了系统的复杂性
-
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
2.策略模式
策略模式(Strategy Pattern)是一种常见的设计模式,它定义了一族算法,将每个算法都封装起来,让它们之间可以互相替换。策略模式可以使得算法独立于使用它的客户端而独立变化,从而可以让客户端在不修改源代码的情况下改变算法的使用方式。
这里是一个使用策略模式实现排序的示例代码。假设有一个Sorter类,它可以使用不同的排序算法来对一个整数数组进行排序,其中具体使用哪个算法由客户端代码指定。
首先,需要定义一个接口SortStrategy,表示一个排序算法。这个接口包含一个排序方法sort,它接受一个整数数组作为参数,并返回排序后的数组:
public interface SortStrategy {int[] sort(int[] array);
}
接下来,可以定义具体的排序算法。这里,我们实现了两种排序算法:冒泡排序和快速排序。它们都实现了SortStrategy接口:
public class BubbleSort implements SortStrategy {public int[] sort(int[] array) {// 冒泡排序算法的具体实现// ...return sortedArray;}
}public class QuickSort implements SortStrategy {public int[] sort(int[] array) {// 快速排序算法的具体实现// ...return sortedArray;}
}
现在,我们可以定义Sorter类了。它包含一个sort方法,它接受一个整数数组和一个排序策略作为参数。排序策略是一个实现了SortStrategy接口的类的实例。Sorter类的sort方法使用传入的排序策略来对数组进行排序
public class Sorter {private SortStrategy strategy;public void setStrategy(SortStrategy strategy) {this.strategy = strategy;}public int[] sort(int[] array) {return this.strategy.sort(array);}
}
最后,可以在客户端代码中使用Sorter类来对数组进行排序了。先创建一个整数数组,然后创建一个Sorter对象,并将排序策略设置为冒泡排序。然后,使用Sorter对象的sort方法对数组进行排序,并将结果打印出来。接着,将排序策略设置为快速排序,再次对数组进行排序,并将结果打印出来
public static void main(String[] args) {int[] array = {5, 2, 4, 6, 1, 3};Sorter sorter = new Sorter();sorter.setStrategy(new BubbleSort());int[] sortedArray = sorter.sort(array);System.out.println(Arrays.toString(sortedArray)); // 输出 [1, 2, 3, 4, 5, 6]sorter.setStrategy(new QuickSort());sortedArray = sorter.sort(array);System.out.println(Arrays.toString(sortedArray)); // 输出 [1, 2, 3, 4, 5, 6]
}
策略模式是一种行为型设计模式,它可以动态地更改一个类的行为。
在这个代码中,我们有两种排序算法:BubbleSort 和 QuickSort。
在 Sorter 类中,我们使用策略模式,以便动态地选择要使用的排序算法。
在主类 Main 中,我们创建了一个 Sorter 对象,并使用 BubbleSort 算法排序。
然后,我们可以通过使用 setSortStrategy() 方法更改要使用的排序算法。
其实策略模式和模板模式很相似,但又不相同,我们看下一章:详述java的设计模式(三)
相关文章:
详述java的设计模式(三)
1.装饰者模式 装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 使用场景: 在不影响其他对象的情况下ÿ…...
Linux命令·pwd
Linux中用 pwd 命令来查看”当前工作目录“的完整路径。 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录。 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。1.命令格式:pwd [选项…...
以图搜图服务快速搭建
以图搜图服务快速搭建 电商公司,管理的商品少则几千,多则上百万。如何帮助用户从多如牛毛的商品中找到类似的商品就成了问题。 以图搜图就可以很好的帮助解决这个问题,通过 Towhee(resnet50 模型) Milvus 如何实现本…...
【TensorFlow安装踩坑记录】
TensorFlow安装踩坑记录第一步,切换服务器cuda版本第二步,conda安装tensorflow记录一下最近安装Tensorflow v1时遇到的问题和解决办法第一步,切换服务器cuda版本 首先我想安装tensorflow 1.13.1,兼容的cuda版本是10.0,…...
03.03回溯法
class Solution { public:vector<int> temp;vector<vector<int>> ans;void dfs(int cur,int n,int k){//剪枝 temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 tempif(temp.size()(n-cur1)<k){return;}if(temp.size()k){ans…...
I.MX6ULL内核开发0:linux内核模块
目录 简要 一、内核模块的概念 二、内核模块加载、卸载过程 简要 1、内核模块的概念 2、内核模块的原理:内核模块在内核的加载、卸载过程。 一、内核模块的概念 内核,是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最…...
qsort快速排序的实现以及模拟实现qsort的功能(狠狠的拿捏)
当你为错过太阳而哭泣的时候,你也要再错过群星了。 --泰戈尔 目录 一.qsort快速排序的实现 二.模拟实现一个qsort功能的函数 一.qsort快速排序的实现 下面是 qsort() 函数的声明: void qsort(void *base, size_t nitems, size_t size, int (…...
[Java·算法·中等]LeetCode215. 数组中的第K个最大元素
每天一题,防止痴呆题目示例分析思路1题解1分析思路2题解2分析思路3题解3👉️ 力扣原文 题目 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不…...
xgboost:算法数学原理
xgboost算法数学原理 1、求预测值 y^iϕ(xi)∑k1Kfk(xi),fk∈F,(1)\hat{y}_i\phi\left(\mathbf{x}_i\right)\sum_{k1}^K f_k\left(\mathbf{x}_i\right), \quad f_k \in \mathcal{F},\tag{1} y^iϕ(xi)k1∑Kfk(xi),fk∈F,(1) F{f(x)wq(x)}(q:Rm→T,w∈RT)\mathca…...
map、multimap、unordered_map
引用:windows程序员面试指南 map map 红黑树 map 对value值无要求 map 有序,按照key值自动排序 map key值唯一 map 头文件:#include map 支持重载[]的运算符 map 为保持有序性,erase()开销大 multimap multimap 红黑树 multim…...
2023年全国最新会计专业技术资格精选真题及答案11
百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 一、选择题 1.下列各项中,仅将生产过程中消耗的变动成本计入产品成本…...
Centos7搭建NFS
1.NFS简介Network File System(网络文件系统,通过网络让不同的机器系统之间可以彼此共享文件和目录,类似Samba服务。2.NFS挂载原理 在网络中服务器和客户端进行连接都是通过端口进行数据传输,而NFS服务端的端口是随机的,从而导致N…...
ThreadLoca基本使用以及与synchronized的区别
文章目录1. ThreadLocal介绍1.1 官方介绍1.2 基本使用1.2.1 常用方法1.2.2 使用案例1.3 ThreadLocal类与synchronized关键字1.3.1 synchronized同步方式1.3.2 ThreadLocal与synchronized的区别2. 运用场景_事务案例2.1 转账案例2.1.1 场景构建2.1.2 引入事务2.2 常规解决方案2.…...
【C++】纯虚函数、纯虚析构
纯虚函数语法:virtual 返回值类型 函数名(参数列表) 0纯虚函数的作用:不用定义!在多态中,通常父类中虚函数的实现是无意义的(因为主要用子类重写的,父类只是为了派生子类当做一个类族的顶层出现࿰…...
Python 进阶小技巧:7招展开嵌套列表
大家好,今天给大家讲解一个Python的进阶知识点:如何将一个嵌套的大列表展开形成一个列表。 小编提供了7种方法供大家学习参考: for循环 列表推导式 使用第三方库itertools 使用sum函数 python自加() 使用extend函…...
【Spring6】| Bean的作用域
目录 一:Bean的作用域 1. singleton(单例) 2. prototype(多例) 3. 其它scope 4. 自定义scop(了解) 一:Bean的作用域 1. singleton(单例) (1…...
Qt界面美化之自定义qss样式表
原生的QT界面不好看,有时候需要根据美工的设计图修改样式。如果使用QML的话搞界面是快,但是QML有点儿吃内存,有时简单的功能还是用传统c的widget方便些。好在有qss,传统界面也可以美化的。QSS称为Qt Style Sheets也就是Qt样式表&a…...
春招进行时:“211文科硕士吐槽工资5500” HR:行情和能力决定价值
学历重要,还是能力重要? 春招进行时,不少学生求职遇冷,会把原因归结为学历水平不够高、毕业院校不够档次、专业不够热门、非一线城市就业机会少等等。 直到上海一位211大学的文科男硕士,吐槽招聘会提供的岗位薪资待遇…...
【DaVinci Developer专题】-45-自动生成SWC中所有Runnable对应的C文件
点击返回「Autosar从入门到精通-实战篇」总目录 案例背景(共5页精讲): 在DaVinci Developer中,以Test_A_SWC的Runnable为例,见图0-1。我们现在尝试自动生成一个包含Test_A_SWC_Init和Test_A_SWC_Main函数原型(也是适用于 C/S Port Serve Runnable)的C文件。 图0-1 目…...
redis启动和关闭服务脚本
编译安装redis,自己写了个脚本。 简单实现启动、关闭和 查看redis服务。 基本流程如下: 脚本执行,必须附带1个参数,没有参数会提示附带参数。 脚本会获取redis-server进程数量。作为开启、关闭以及查看redis服务的数据依据。 …...
PotPlayer跨语言字幕解决方案:基于百度翻译API的实时字幕转换工具
PotPlayer跨语言字幕解决方案:基于百度翻译API的实时字幕转换工具 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu 在全球化…...
Flutter透明视频播放实战:用AlphaPlayer插件5分钟搞定礼物特效
Flutter透明视频播放实战:用AlphaPlayer插件5分钟搞定礼物特效 在移动应用开发中,炫酷的动画效果往往能显著提升用户体验,尤其是在社交、直播和游戏类应用中。透明视频特效作为其中一种高级表现形式,能够实现元素与背景的无缝融合…...
数字中国新引擎:产业经济大脑的全景式解构与深度洞察(PPT)
“中国经济高质量发展的核心命题,已从‘有没有’转向‘好不好’。而要回答‘好不好’,就必须构建一套能看清、看准、看远的‘经济慧眼’。”在数字经济成为国家战略主战场的今天,地方政府正面临着前所未有的治理挑战:宏观政策如何…...
计算机毕业设计springboot足球俱乐部管理系统 基于SpringBoot的青少年足球培训综合服务平台的设计与实现 基于SpringBoot架构的足球青训营数字化运营系统的设计与实现
计算机毕业设计springboot足球俱乐部管理系统(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着足球运动的全球普及和竞技水平的持续提升,青少年足球培训已成为各国…...
从零到数据分析:用ClickHouse+DBeaver在Windows上复现一个电商用户行为查询
从零构建电商数据分析平台:Windows下ClickHouse与DBeaver实战指南 1. 为什么选择ClickHouse进行电商行为分析? 去年双十一期间,某头部电商平台通过实时分析用户点击流数据,在活动开始后30分钟内就调整了首页推荐策略,…...
告别Joplin!用MarkDownload+Obsidian打造你的网页剪藏工作流(附完整配置JSON)
从Joplin到Obsidian:用MarkDownload构建高效网页剪藏系统 每次在网上冲浪时遇到值得保存的内容,你是否也经历过这样的困境?收藏夹里堆满了再也找不到的链接,或是剪藏工具中杂乱无章的片段。作为一个长期依赖Joplin进行知识管理的用…...
桶排序:分布式排序的高效实现
桶排序:分布式排序的高效实现 算法原理 核心思路 桶排序是一种分布式排序算法,其核心思想是: 将待排序的数据分到有限数量的桶里每个桶再分别进行排序(可以使用其他排序算法)最后将各个桶中的数据有序地合并起来 复杂度…...
建行江门市分行:银发关爱在行动 暖心服务送到家
服务无边界。近日,建行广东江门分行辖内多家网点接连上演暖心一幕,员工们主动跨出柜台,将金融服务送到客户家中、病房前,用一次次“特事特办”的上门服务,化解客户的“燃眉之急”,生动诠释了“以客户为中心…...
30分钟零基础入门:DJI Cloud API Demo实现无人机云平台集成的完整指南
30分钟零基础入门:DJI Cloud API Demo实现无人机云平台集成的完整指南 【免费下载链接】DJI-Cloud-API-Demo 项目地址: https://gitcode.com/gh_mirrors/dj/DJI-Cloud-API-Demo DJI Cloud API Demo是一个开源项目,主要功能是帮助开发者快速实现无…...
PROFINET通信避坑指南:PN/PN耦合器在S7系列PLC中的3种典型应用场景解析
PROFINET通信避坑指南:PN/PN耦合器在S7系列PLC中的3种典型应用场景解析 在工业自动化领域,PROFINET通信的稳定性和可靠性直接关系到生产线的运行效率。PN/PN耦合器作为跨子网通信的关键设备,其配置方式的选择往往让工程师陷入纠结。本文将深入…...
