设计模式例子
策略模式(Strategy Pattern)
-
策略模式 (Strategy Pattern):
- 定义一系列算法,将每个算法都封装起来,并使它们之间可以互换。
- 例如:
java.util.Comparator
以下是一个简单的Java策略模式的例子,涉及一个商品的价格计算场景。我们将定义一个PriceCalculator类,它使用不同的价格计算策略来计算商品的最终价格。
import java.util.HashMap;
import java.util.Map;// 策略接口
interface PricingStrategy {double calculatePrice(double originalPrice);
}// 具体策略1:打折策略
class DiscountPricingStrategy implements PricingStrategy {private double discountRate;public DiscountPricingStrategy(double discountRate) {this.discountRate = discountRate;}@Overridepublic double calculatePrice(double originalPrice) {return originalPrice * (1 - discountRate);}
}// 具体策略2:满减策略
class FullReductionPricingStrategy implements PricingStrategy {private double threshold;private double reductionAmount;public FullReductionPricingStrategy(double threshold, double reductionAmount) {this.threshold = threshold;this.reductionAmount = reductionAmount;}@Overridepublic double calculatePrice(double originalPrice) {return originalPrice >= threshold ? originalPrice - reductionAmount : originalPrice;}
}// 上下文类,用于设置和执行策略
class PriceCalculator {private PricingStrategy pricingStrategy;public void setPricingStrategy(PricingStrategy pricingStrategy) {this.pricingStrategy = pricingStrategy;}public double calculateFinalPrice(double originalPrice) {if (pricingStrategy == null) {throw new IllegalStateException("Pricing strategy not set");}return pricingStrategy.calculatePrice(originalPrice);}
}public class StrategyPatternExample {public static void main(String[] args) {// 创建商品价格计算器PriceCalculator priceCalculator = new PriceCalculator();// 商品原始价格double originalPrice = 100.0;// 使用打折策略PricingStrategy discountStrategy = new DiscountPricingStrategy(0.2);priceCalculator.setPricingStrategy(discountStrategy);double discountedPrice = priceCalculator.calculateFinalPrice(originalPrice);System.out.println("Discounted Price: " + discountedPrice);// 使用满减策略PricingStrategy fullReductionStrategy = new FullReductionPricingStrategy(80.0, 10.0);priceCalculator.setPricingStrategy(fullReductionStrategy);double reducedPrice = priceCalculator.calculateFinalPrice(originalPrice);System.out.println("Reduced Price: " + reducedPrice);}
}
这个例子中,PricingStrategy是一个策略接口,具体的打折策略和满减策略分别实现了这个接口。PriceCalculator是上下文类,用于设置和执行不同的策略。在main方法中,我们创建了一个商品价格计算器,分别使用了打折策略和满减策略来计算最终价格。你可以运行这个例子,看到不同策略下的最终价格计算结果。
观察者模式(Observer Pattern)
- 定义了一种一对多的依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
- 例如:
java.util.Observer和java.util.Observable
当涉及观察者模式时,通常会有一个主题对象(Subject),它会维护一个观察者(Observer)列表,并通知这些观察者当其状态发生改变。下面是一个简单的 Java 观察者模式示例,模拟了一个简单的新闻发布系统。
import java.util.ArrayList;
import java.util.List;// 主题接口
interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers(String news);
}// 具体主题类
class NewsPublisher implements Subject {private List<Observer> observers;private String latestNews;public NewsPublisher() {this.observers = new ArrayList<>();}@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String news) {for (Observer observer : observers) {observer.update(news);}}// 模拟新闻发布public void publishNews(String news) {this.latestNews = news;notifyObservers(news);}
}// 观察者接口
interface Observer {void update(String news);
}// 具体观察者类
class NewsSubscriber implements Observer {private String subscriberName;public NewsSubscriber(String subscriberName) {this.subscriberName = subscriberName;}@Overridepublic void update(String news) {System.out.println(subscriberName + " received news: " + news);}
}public class ObserverPatternExample {public static void main(String[] args) {// 创建新闻发布者NewsPublisher publisher = new NewsPublisher();// 创建订阅者Observer subscriber1 = new NewsSubscriber("Subscriber 1");Observer subscriber2 = new NewsSubscriber("Subscriber 2");// 订阅新闻publisher.registerObserver(subscriber1);publisher.registerObserver(subscriber2);// 发布新闻publisher.publishNews("Breaking News: Observers pattern example!");// 移除一个订阅者publisher.removeObserver(subscriber2);// 再次发布新闻publisher.publishNews("Second Edition: More updates!");}
}
这个示例中,NewsPublisher 是主题类,负责管理观察者列表并通知它们有关最新新闻的更新。NewsSubscriber 是具体的观察者类,实现了 Observer 接口。在 main 方法中,创建了一个新闻发布者,并添加了两个订阅者。当发布者发布新闻时,所有订阅者都会收到相应的新闻更新。可以运行这个示例来查看观察者模式的效果。
模板方法模式(Template Method Pattern)
- 定义一个算法的骨架,将一些步骤延迟到子类中。
- 例如:
java.util.Collections#sort()
模板方法模式通常涉及一个抽象类定义了一个算法的骨架,将一些步骤延迟到子类中。以下是一个简单的 Java 模板方法模式的例子,模拟了一种饮料制作的过程。
// 模板方法抽象类
abstract class BeverageTemplate {// 模板方法,定义了饮料制作的步骤public final void makeBeverage() {boilWater();brew();pourInCup();addCondiments();System.out.println("Beverage is ready!");}// 具体步骤1:烧水private void boilWater() {System.out.println("Boiling water");}// 具体步骤2:冲泡protected abstract void brew();// 具体步骤3:倒入杯中private void pourInCup() {System.out.println("Pouring into cup");}// 具体步骤4:加调料protected abstract void addCondiments();
}// 具体类1:制作咖啡
class Coffee extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("Brewing coffee grounds");}@Overrideprotected void addCondiments() {System.out.println("Adding sugar and milk");}
}// 具体类2:制作茶
class Tea extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("Steeping the tea");}@Overrideprotected void addCondiments() {System.out.println("Adding lemon");}
}public class TemplateMethodPatternExample {public static void main(String[] args) {// 制作咖啡BeverageTemplate coffee = new Coffee();System.out.println("Making coffee...");coffee.makeBeverage();System.out.println();// 制作茶BeverageTemplate tea = new Tea();System.out.println("Making tea...");tea.makeBeverage();}
}
在这个例子中,BeverageTemplate 是模板方法抽象类,它定义了一个 makeBeverage 模板方法,其中包含了制作饮料的通用步骤,如烧水、冲泡、倒入杯中和加调料。Coffee 和 Tea 是具体的子类,分别实现了 brew 和 addCondiments 方法以定制制作咖啡和茶的具体步骤。
在 main 方法中,创建了一个咖啡对象和一个茶对象,并分别调用它们的 makeBeverage 方法。你可以运行这个示例来查看模板方法模式的实际应用。
相关文章:
设计模式例子
策略模式(Strategy Pattern) 策略模式 (Strategy Pattern): 定义一系列算法,将每个算法都封装起来,并使它们之间可以互换。例如:java.util.Comparator 以下是一个简单的Java策略模式的例子,涉及一个商品的…...
腾讯云入侵
早上8点左右收到腾讯云的相关短信,提示机器可能存在挖坑风险。马上登录机器看了一下,发现crontab有个比较诡异的任务 [devVM_0_12_centos ~]$ crontab -l 11 * * * * /home/dev/.config/systemd/user/systemd-tmpfiles-cleanup/systemd-tmpfiles-cleanu…...
第二章 智能家居子系统——C51单片机 配置波特率115200
前言 本章为智能家居项目的第二章,本章主要写51单片机的定时器timer,串口UART,中断,外接模块DHT11 同项目其他博文: 项目的概述链接:Linux智能家居项目概述-CSDN博客 第一章 主控代码开发链接:…...
registry镜像仓库通过HTTP API删除镜像
registry组件提供了HTTP的接口,可以参考:官网API说明 删除思路: 镜像由多个layers层组成,DELETE /v2/<name>/blobs/<digest>可以用来删除一个单独的层,但是我们的目的不是要删除层。 我们用DELETE /v2/…...
【ATTCK】ATTCK视角下的水坑钓鱼攻防战法
在网络安全领域,ATT&CK已经成为了研究和理解恶意攻击者行为的重要工具。站在攻击者的视角,ATT&CK为我们描绘了他们在攻击过程中所使用的各种战术、技术和常见知识。本文将结合ATT&CK框架,对水坑钓鱼攻击进行深入分析,…...
【算法】算法题-20231115
这里写目录标题 一、回文数(力扣第九题)二、剑指 Offer 39. 数组中出现次数超过一半的数字三、至少是其他数字两倍的最大数(leetcode第747题,飞书三面)四、给定一有序整型数组,其中存在有重复元素ÿ…...
Rabin Karp 字符匹配算法
Rabin Karp 字符匹配算法 相关题目: 187. 重复的DNA序列 28. 找出字符串中第一个匹配项的下标 class FindRepeatedDnaSequences:"""187. 重复的DNA序列https://leetcode.cn/problems/repeated-dna-sequences/description/"""def sol…...
星宿UI2.51资源付费变现小程序 支持流量主广告投放
目前,最新版的星宿UI是2.51版本。要搭建星宿UI,您需要准备备用域名、服务器和微信小程序账号。星宿UI提供了多项功能,包括文章展示、文章分类、资源链接下载和轮播图等。此外,还支持直接下载附件功能。这些功能使得星宿UI非常适合…...
Telnet 测试 UDP 端口?
Telnet 并不支持 UDP 端口的测试,可以使用 nc 命令来进行测试。nc 命令两种都支持: TCP # nc -z -v -u [hostname/IP address] [port number] # nc -z -v 192.168.10.12 22 Connection to 192.118.20.95 22 port [tcp/ssh] succeeded! UDP # nc -z -v…...
【论文复现】常见问题
1. 提取出错 首先检查嵌入时的像素值是否越界(0-255),如果越界则在提取的时候无法正确提取嵌入的时候注意整数除法和浮点数除法向下取整结果不一样,floor(int(10)/16)1,floor(double(10)/16)0 2. 常用代码部分 1.生…...
Uniapp开发 购物商城源码 在线电商商城源码 适配移动终端项目及各小程序
lilishop电商商城系统 商城移动端,使用Uniapp开发,可编译为所有移动终端项目及各小程序 源码下载:https://download.csdn.net/download/m0_66047725/88487579 源码下载2:关注我留言...
xml schema中的sequence的含义
https://www.w3.org/TR/xmlschema-1/#element-sequence xml schema中的sequence的含义:包含的元素必须按规定的顺序出现。通过属性maxOccurs和minOccurs可以定义最多、最少出现的次数。最多可以定义不限制次数,最少可以定义0次。默认是最少出现1次&…...
详解 KEIL C51 软件的使用·建立工程
单片机要运行,就必须将程序代码下载到程序存储器内部,但是在写进单片机之前要先将你写 的程序转换成*.hex 或*.bin 的文件.不同系列的单片机都有不同的软件对其进行编绎,而 keil Cx51 是德国开发的一个专为 51 系列单片机提供的软件开发平台,基本上现在的所有 51 系列内核的单片…...
2023年03月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 已知一个列表lst = [2,3,4,5,6],lst.append(20),print(lst)的结果是?( )(2分) A.[10,2,3,4,5,6,20] B.[20,2,10,3,4,5,6] C.[2,3,4,5,6,20] D.[2,3,4,5,6,10,20] 答案:C 第2…...
nginx 代理服务时遇到的问题
一 nginx代理多个服务,且服务之间需要相互通信 多个服务运行在docker容器中,nginx同样在docker容器中 比如前端服务需要请求后端服务,用户请求服务器80或者443 ,nginx代理请求到前端服务,前端服务业务请求到后端服务…...
利用共享台球室小程序系统提升用户体验
随着移动互联网的普及,越来越多的用户倾向于使用手机应用来解决生活中的问题。共享台球室作为一个结合了传统与现代元素的项目,也需要借助移动小程序的力量来提升用户体验。本文将探讨如何利用共享台球室小程序系统提升用户体验。 一、提供便捷的服务 …...
U-Mail海外邮件中继帮您解决企业邮件退信难题
过去一年,国内外形势严峻复杂,但中国外贸顶住压力、爬坡过坎,进出口规模冲破40万亿元大关,高达42万亿元人民币,中国连续6年位居货物贸易第一大国。随着我国疫情防控措进入新阶段,“拼经济”正在成为各地的一…...
ImageJ灰度值量化分析 实用技巧——免疫组化分析(定量分析篇)
在临床病理诊断中, 免疫组织化学( Immunohistochemistry, IHC) 是一种很重要的技术和手段。 免疫组化标记时细胞阳性着色程度取决于抗原含量、分布密度和标记方法及其敏感性。 一般而言,抗原含量越多,分布密度越高,阳性结果显色…...
了解STM32看门狗定时器的工作原理和原则
STM32 系列微控制器的看门狗定时器 (Watchdog Timer,WWDG) 是一种重要的硬件资源,用于检测系统的异常状态,并在发生异常时执行特定的操作,以确保系统能够正常运行。在本文中,我将详细介绍 STM32 看门狗定时器的工作原理…...
【2014年数据结构真题】
41. (13分)二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。 给定一棵二叉树T,采用二叉链表存储,结点结构如下: 其中叶结点的weight域保存该结点的非负权值。 设root为指向T的根结点的指针, 请设计求T 的WPL…...
拆解Clonezilla镜像:除了partclone,你还需要知道的底层原理与工具链
拆解Clonezilla镜像:从分卷压缩到文件系统的技术全景解析 当我们需要从Clonezilla备份中提取单个文件时,传统方法往往要求完整恢复整个镜像——这种"全有或全无"的方式在存储资源有限的情况下显得尤为笨重。本文将带您深入Clonezilla镜像的底层…...
计算机毕业设计:Python地铁多维度运营分析与数据管理系统 Django框架 数据分析 可视化 大数据 机器学习 深度学习(建议收藏)✅
博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...
知网维普都要过,AI率85%用哪款工具最合适
越来越多高校开始同时要求知网和维普检测,这让选工具变得更复杂了——不是只要过一个平台,而是要同时达标。 AI率85%,知网和维普都要过20%以下,这种情况用哪款工具最合适? 知网和维普的算法差异 先说一个背景知识&a…...
保姆级教程:在Jetson Orin上从零搭建DJI OSDK + ROS2 Humble开发环境(避坑指南)
保姆级教程:在Jetson Orin上从零搭建DJI OSDK ROS2 Humble开发环境(避坑指南) 当无人机遇上边缘计算,Jetson Orin与ROS2的组合正在重新定义自主飞行系统的开发范式。作为大疆生态中最硬核的开发方式,OSDK允许开发者直…...
云原生应用的微服务架构设计
云原生应用的微服务架构设计 引言:微服务架构的重要性 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是单体应用的臃肿和难以维护。在云原生时代,微服务架构已经成为构建现代应用的最佳实践。今天&a…...
Android黑屏别慌!手把手教你用dumpsys和Winscope精准定位问题(附实战案例)
Android黑屏问题深度排查:从dumpsys到Winscope的实战指南 当你的Android设备突然黑屏,那种感觉就像在黑暗中摸索——你不知道问题出在哪里,更不知道如何解决。但别担心,今天我要分享的这套排查方法,将为你点亮一盏明灯…...
UVM实战:RAL寄存器测试全流程详解(含代码示例)
UVM实战:RAL寄存器测试全流程详解(含代码示例) 在芯片验证领域,寄存器测试是确保硬件功能正确性的关键环节。UVM(Universal Verification Methodology)作为行业标准验证方法学,其内置的RAL&…...
避坑指南:ShardingSphere引入后SpringBoot启动变慢的3种常见原因及解决方案
ShardingSphere集成SpringBoot启动优化实战:从原理到解决方案 最近在技术社区看到不少开发者反馈,SpringBoot项目引入ShardingSphere后启动时间明显变长。这确实是个值得深入探讨的问题——作为分布式数据库中间件的标杆产品,ShardingSphere的…...
PHP反序列化漏洞实战:从NewStarCTF题目看私有属性的坑
PHP反序列化漏洞实战:私有属性处理中的隐藏陷阱 在CTF竞赛和实际渗透测试中,PHP反序列化漏洞一直是Web安全领域的重点研究对象。而其中关于类属性可见性(特别是private修饰符)的处理机制,往往成为解题的关键突破口。去…...
SA8775学习笔记(一)一颗 SA8775P,能不能撑起舱驾一体?从架构到实战彻底讲透(多屏+多摄+AI+安全全解析)
🚗🔥 一颗 SA8775P,能不能撑起舱驾一体?从架构到实战彻底讲透(多屏+多摄+AI+安全全解析) 🧩 一、先说结论:SA8775P不是“更强”,而是在重构整车电子架构 如果从参数看 SA8775P,很容易误判它只是“性能更强的一颗芯片”。 但放到真实整车架构里,它干的事情其实是:…...
