【设计模式】单例模式、工厂模式、策略模式、观察者模式、装饰器模式

devtools/2024/9/18 12:53:20/ 标签: 设计模式, 单例模式, 策略模式

1 单例模式
2 工厂模式
3 策略模式
4 观察者模式
5 装饰器模式

1 单例模式

class Singleton:"""单例模式:确保一个类只有一个实例,并提供一个全局访问点。在需要全局状态或者需要频繁创建和销毁实例会导致性能问题时非常有用。"""_instance = Nonedef __new__(cls, *args, **kwargs):"""创建实例时调用,确保只有一个实例。:param args: 位置参数:param kwargs: 关键字参数:return: 唯一实例"""if cls._instance is None:cls._instance = super(Singleton, cls).__new__(cls)return cls._instancedef __init__(self, value=None):"""初始化实例属性。:param value: 初始化值"""# 使用一个类属性来检查实例是否已初始化if not hasattr(self, '_initialized'):self.value = valueself._initialized = True# 示例用法
singleton1 = Singleton(10)
singleton2 = Singleton(20)print(singleton1.value)  # 输出: 10
print(singleton2.value)  # 输出: 10
print(singleton1 is singleton2)  # 输出: True

2 工厂模式

class AnimalFactory:"""工厂模式用于创建对象,而不需要指定将要创建的具体类。这在需要将对象创建的代码与使用对象的代码分离时非常有用,提高了代码的灵活性和扩展性。工厂模式提供了一个方法来创建对象,客户端代码只需调用这个方法,而无需了解如何创建对象的详细信息。"""@staticmethoddef create_animal(animal_type):"""根据指定的动物类型创建并返回对应的动物对象。:param animal_type: 要创建的动物类型('dog' 或 'cat'):return: 对应的动物对象(Dog 或 Cat):raises ValueError: 如果指定的 animal_type 无效,则抛出异常"""if animal_type == 'dog':return Dog()  # 创建并返回 Dog 类的实例elif animal_type == 'cat':return Cat()  # 创建并返回 Cat 类的实例else:raise ValueError(f"Unknown animal type: {animal_type}")  # 如果 animal_type 无效,抛出异常# 示例用法
dog = AnimalFactory.create_animal('dog')
print(dog)  # 输出: <__main__.Dog object at ...># 如果需要一个 Cat 实例
cat = AnimalFactory.create_animal('cat')
print(cat)  # 输出: <__main__.Cat object at ...>

3 策略模式

class Strategy:"""策略模式定义了一系列算法,并将每一个算法封装起来,使他们可以互换。这在需要根据不同情况使用不同算法或行为时非常有用"""def execute(self):"""执行策略的方法,具体策略类需要实现此方法。:return: 策略的执行结果"""passclass ConcreateStrategyA(Strategy):"""具体策略类A:实现了 Strategy 接口,定义了特定的策略行为。"""def execute(self):"""实现具体的策略行为。:return: 表示具体策略 A 的执行结果"""return "ConcreateStrategyA"class Context:"""上下文类:维护一个 Strategy 对象的引用,并允许在运行时设置或更改策略。上下文类依赖于策略接口,并将策略的执行委托给具体的策略类。"""def __init__(self, strategy: Strategy):"""初始化上下文对象时传入一个策略对象。:param strategy: 一个 Strategy 类型的策略对象"""self._strategy = strategydef set_strategy(self, strategy: Strategy):"""设置或更改策略对象。:param strategy: 一个 Strategy 类型的策略对象"""self._strategy = strategydef do_action(self):"""执行当前策略的行为。:return: 策略的执行结果"""return self._strategy.execute()# 示例用法
strategy_a = ConcreateStrategyA()  # 创建具体策略 A 的实例
context = Context(strategy_a)  # 使用策略 A 初始化上下文对象
print(context.do_action())  # 输出: ConcreateStrategyA# 可以更改策略
class ConcreateStrategyB(Strategy):"""具体策略类B:实现了 Strategy 接口,定义了另一种策略行为。"""def execute(self):"""实现具体的策略行为。:return: 表示具体策略 B 的执行结果"""return "ConcreateStrategyB"strategy_b = ConcreateStrategyB()  # 创建具体策略 B 的实例
context.set_strategy(strategy_b)  # 将上下文的策略更改为策略 B
print(context.do_action())  # 输出: ConcreateStrategyB

4 观察者模式

class Subject:"""观察者模式定义了对象之间一对多依赖关系,当一个对象状态发送改变时,所有依赖于他的对象都会得到通知并自动更新这在需要实现时间驱动的系统时非常有用"""def __init__(self):"""初始化主题对象,创建一个空的观察者列表。"""self._observers = []  # 存储所有注册的观察者对象def attach(self, observer):"""将一个新的观察者对象添加到观察者列表中。:param observer: 需要注册的观察者对象"""self._observers.append(observer)def detach(self, observer):"""从观察者列表中移除一个观察者对象。:param observer: 需要移除的观察者对象"""self._observers.remove(observer)def notify(self):"""通知所有观察者,调用它们的 update 方法。"""for observer in self._observers:observer.update()  # 调用每个观察者的 update 方法class Observer:"""观察者(Observer)抽象类:定义了一个更新接口,具体的观察者类需要实现该接口以响应主题的通知。"""def update(self):"""当主题通知时,调用此方法以更新观察者的状态。具体观察者类需要实现此方法。"""passclass ConcreateObserverA(Observer):"""具体观察者A(ConcreateObserverA)类:实现了 Observer 接口,并定义了具体的更新行为。"""def update(self):"""实现观察者的更新行为,当主题通知时调用。"""print('ConcreateObserverA notified')  # 打印通知信息# 示例用法
subject = Subject()  # 创建主题对象
observer_a = ConcreateObserverA()  # 创建具体观察者A的实例
subject.attach(observer_a)  # 将观察者A注册到主题中# 当主题状态发生变化时,通知所有观察者
subject.notify()  # 输出: ConcreateObserverA notified

5 装饰器模式

class Component:"""装饰器模式允许所有用户在不修改对象的情况下,向对象添加新的龚这在需要动态地给对象添加功能时非常有用组件抽象类(Component):定义一个接口,用于所有具体组件和装饰器类。装饰器模式允许在不修改对象本身的情况下,动态地为对象添加新的功能。这在需要扩展对象的功能且不希望影响其他对象时非常有用。"""def do_something(self):"""执行某种操作的方法。具体组件和装饰器类都需要实现这个方法。"""passclass ConcreteComponent(Component):"""具体组件类(ConcreteComponent):实现了 Component 接口,定义了具体的行为。装饰器将为这个类动态地添加额外的功能。"""def do_something(self):"""实现具体的操作。在装饰器模式中,装饰器将在此操作的基础上添加额外的功能。"""print("ConcreteComponent's behavior")class DecoratorA(Component):"""具体装饰器类A(DecoratorA):继承自 Component 并包含一个 Component 对象的引用。通过组合的方式,将额外的功能添加到该组件中。"""def __init__(self, component: Component):"""初始化装饰器,并将一个 Component 对象传入。:param component: 被装饰的组件对象"""self._component = component  # 持有被装饰组件的引用def do_something(self):"""执行被装饰组件的原有操作,并添加额外的行为。"""self._component.do_something()  # 调用被装饰组件的原有操作self.additional_behavior()  # 添加装饰器A的额外行为def additional_behavior(self):"""定义装饰器A的额外行为。此方法在装饰器的 do_something 方法中调用,作为对原有操作的扩展。"""print('Additional behavior of DecoratorA')# 示例用法
component = ConcreteComponent()  # 创建具体组件实例
decorator = DecoratorA(component)  # 使用 DecoratorA 装饰组件
decorator.do_something()  # 输出: ConcreteComponent's behavior
#       Additional behavior of DecoratorA

http://www.ppmy.cn/devtools/102361.html

相关文章

大数据学习路线基础指南‌

随着信息技术的迅猛发展&#xff0c;‌大数据已成为当今社会的热门话题。‌无论是企业决策、‌市场分析还是科学研究&#xff0c;‌大数据都扮演着举足轻重的角色。‌对于想要投身这一领域的学习者来说&#xff0c;‌制定一份清晰、‌系统的大数据学习路线是至关重要的。‌提供…

罗德与施瓦茨RS、UPV 音频分析仪 250KHZ 双通道分析仪UPL

罗德与施瓦茨 UPV 音频分析仪的规格包括&#xff1a; 模拟 双通道分析仪&#xff1a;带宽高达 250 kHz 生成正弦波信号&#xff1a;单通道最高 185 kHz&#xff08;需要 B1&#xff09;和双通道最高 80 kHz FFT本底噪声&#xff1a;< -140dB 固有频率响应&#xff08;20 …

计算机毕业设计选题推荐-高中素质评价档案系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

【JS】使用MessageChannel实现深度克隆

前言 通常使用简便快捷的JSON 序列化与反序列化实现深克隆&#xff0c;也可以递归实现或者直接使用lodash。 但 JSON 序列化与反序列化 无法处理如下的循环引用&#xff1a; 实现 MessageChannel 内部使用了浏览器内置的结构化克隆算法&#xff0c;该算法可以在不同的浏览器上…

c#入门篇5

目录 一、常量 二、枚举 1、枚举类型和int以及string类型之间的转换 2、注意事项 强制转换&#xff08;Explicit Casting&#xff09;&#xff1a; Enum.Parse 和 Enum.TryParse&#xff1a; 三、结构 定义方式&#xff1a;结构体使用 struct 关键字进行定义。结构体通常用…

科技在教育领域的创新应用与在工作场所的智能化转型

随着信息技术的迅猛发展&#xff0c;‌科技正以前所未有的速度改变着我们的生活、‌学习和工作方式。‌其中&#xff0c;‌教育领域和工作场所作为社会的重要组成部分&#xff0c;‌也迎来了深刻的变革。‌ 在教育领域&#xff0c;‌科技的创新应用为传统教学模式带来了颠覆性…

命令模式与宏命令:批量操作的高效实现

目录 引言 背景与重要性命令模式与宏命令概述 命令模式的基础概念 命令模式的定义与结构关键组件及其角色命令模式的优点与缺点 命令模式的应用场景 用户操作记录与撤销/重做请求队列与任务调度GUI操作的解耦 宏命令的引入与发展 宏命令的定义与结构宏命令与命令模式的关系宏…

5.2二叉树——堆

本篇博客梳理一个重要的数据结构——堆 注意&#xff1a;若无特殊说明&#xff0c;默认是小堆进行分析 一、堆的概念与分类 1&#xff0e;堆是完全二叉树 2&#xff0e;大堆&#xff1a;父亲≥孩子&#xff1b;小堆&#xff1a;父亲≤孩子 注意&#xff1a;兄弟之间无法确定…

视频中间件:大华视频设备接入管理应用

前言 上篇博文介绍了视频中间件&#xff1a;海康视频设备的接入管理&#xff1f;&#xff0c;今天给大家带来大华视频设备的接入管理&#xff0c;视频中间件平台支持大华Sdk、大华主动注册、Onvif、Rtsp、Gb28181等方式对大华视频设备的接入管理。同时视频中间件可支持协议互转…

力扣面试150 插入区间 模拟

Problem: 57. 插入区间 &#x1f468;‍&#x1f3eb; 代码随想录 模拟 ⏰ 时间复杂度&#xff1a; O ( n ) O(n) O(n) class Solution {public int[][] insert(int[][] intervals, int[] newInterval) {int idx 0;List<int[]> res new ArrayList<>();while (…

Hadoop联邦模式搭建

在Hadoop架构中提供了三类搭建方式&#xff0c;第一类是给测试或开发人员使用的伪分布式或单NN节点搭建方式&#xff0c;第二类是用来商用化并解决NN单点故障的HA搭建方式&#xff0c;第三类就是这里要说的联邦模式&#xff0c;它本身也是一种供给商用的模式&#xff0c;但是它…

MySql 忘记 Root 密码

停止 mysql 服务 linux 安装时&#xff0c;使用 $> mysqld_safe --usermysql & 启动&#xff0c;所以关闭时&#xff0c;直接 ps 查询进程&#xff0c;并关闭该进程即可 使用如下命令查询进程号&#xff0c;把 mysql 对应的进程都关闭即可 $> ps -ef | grep mysql …

openjdk与jdk的区别是什么

OpenJDK与JDK的主要区别在于他们的开放性和许可证。 开放性&#xff1a;OpenJDK是一个开放源代码的Java开发工具包&#xff0c;由Oracle公司主导并以GPL许可证发布。它的源代码是公开可用的&#xff0c;任何人都可以查看、修改和分发。而JDK&#xff08;Java Development Kit&a…

Salesforce篇——如何在lightning页面添加ListviewButton使用lwc组件

1.创建lwc组件&#xff0c;用于展示listview已选数据&#xff1a; html&#xff1a; <template><lightning-card title"Selected Records"><p>Selected Record IDs: {selectedIds}</p><lightning-button label"返回" onclick…

如何制作带密码权限的视频二维码?

原创内容&#xff0c;2024.8.28&#xff0c;长沙 如何制作带密码权限的视频二维码&#xff1f;实现输入密码才能正常观看。您可以在酷播云平台上生成带密码功能的视频二维码&#xff0c;您可以按照以下步骤操作&#xff1a;第一步&#xff1a;注册平台账号 首先&#xff0c;您…

【Material-UI】RadioGroup组件:单选按钮组详解

文章目录 一、RadioGroup 组件概述1. 组件介绍2. 基本用法 二、RadioGroup 的关键特性1. 布局方向2. 受控组件3. 表单集成 三、RadioGroup 的实际应用场景1. 用户偏好选择2. 付款方式选择 四、总结 Material-UI 是一个广泛使用的 React UI 框架&#xff0c;提供了丰富的组件库以…

云计算架构师韩先超对咪咕进行【K8S超大规模集群与AI赋能算力网络调度】培训...

2024年8月22号和23号&#xff0c;云计算架构师韩先超对咪咕进行【K8S超大规模集群与AI赋能算力网络调度培训】现场。

SQLi-LABS 通关攻略【36-40】

SQLi-LABS 36关 1.本关依旧是宽字节注入 2.测试闭合方式 ?id1 //正常显示 ?id1 //显示错误 ?id1%df //显示错误 ?id1%df -- //显示正常 3.测试回显点 ?id-1%df%27…

关于java中Excel的导入导出

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、配置pom依赖二、搭建utils工具类1.Excel表头设置表2.Excel导入导出工具类3.Excel导出配置4.Excel导入配置 三、添加user表和工具类使用方法1.user表设置2.工…

Android App启动流程

1.通过 Launcher 启动应用时&#xff0c;点击应用图标后&#xff0c;Launcher 调用 startActivity 启动应用。 2.Launcher Activity 最终调用 Instrumentation 的 execStartActivity 来启动应用。 3.Instrumentation 调用 ActivityManagerProxy (ActivityManagerService 在应…