温州网站推广外包,成都电商网站开发,合肥市城乡建设局,网站建设参考文献创建型设计模式#xff08;Creational Design Patterns#xff09;#xff0c;主要关注对象的创建机制。这类模式可以使得系统更加独立于如何创建、组合和表示其对象。通过将这些职责分离出来#xff0c;创建型设计模式有助于提高代码的灵活性和复用性。 本书的范例代码已经… 创建型设计模式Creational Design Patterns主要关注对象的创建机制。这类模式可以使得系统更加独立于如何创建、组合和表示其对象。通过将这些职责分离出来创建型设计模式有助于提高代码的灵活性和复用性。 本书的范例代码已经放在我的资源库里——pipbook 1 抽象工厂模式
用于创建复杂的对象这种对象由许多小对象组成而这些对象都属于某个特定的系列
例如在GUI系统中可以设计一个“抽象控件工厂”然后在下面设计三个“具体子类工厂”如下图所示
它们都提供同一种对象的方法例如都提供创建按钮的方法等但是可以创建适应不同的平台的方法。
抽象工厂模式的结构
抽象工厂Abstract Factory定义了创建一系列相关产品对象的方法例如createProductA()、createProductB()等。具体工厂Concrete Factory实现了抽象工厂中定义的方法负责实例化具体的产品对象。抽象产品Abstract Product定义了产品的接口可以是一个产品家族的抽象基类。具体产品Concrete Product实现了抽象产品的接口代表某一具体产品的实现。
假设有一个图形应用支持创建不同风格的按钮和文本框。不同风格的按钮和文本框属于不同的产品族例如Windows风格和Mac风格代码结构如下
# 抽象工厂创建按钮和文本框
class GUIFactory:def create_button(self):passdef create_textbox(self):pass# 具体工厂创建win或者mac的按钮和文本框
class WindowsFactory(GUIFactory):def create_button(self):return WindowsButton()def create_textbox(self):return WindowsTextBox()class MacFactory(GUIFactory):def create_button(self):return MacButton()def create_textbox(self):return MacTextBox()# 抽象产品定义按钮和文本框
class Button:def render(self):passclass TextBox:def render(self):pass# 具体产品定义按钮和文本框的风格类型
class WindowsButton(Button):def render(self): # 重写render()print(Rendering Windows button)class MacButton(Button):def render(self):# 重写render()print(Rendering Mac button)class WindowsTextBox(TextBox):def render(self):# 重写render()print(Rendering Windows text box)class MacTextBox(TextBox):def render(self):# 重写render()print(Rendering Mac text box)# 客户端factory 必须是 GUIFactory 类型或其子类
def client_code(factory: GUIFactory):功能创建对象如果传入WindowsFactory()则实际上调用def create_button(self):return WindowsButton()def create_textbox(self):return WindowsTextBox()button factory.create_button()textbox factory.create_textbox()# 使用对象button.render()textbox.render()# 使用不同的工厂
windows_factory WindowsFactory()
client_code(windows_factory)mac_factory MacFactory()
client_code(mac_factory)
优点
解耦客户端不需要依赖具体的产品类只需要依赖抽象工厂接口可以轻松切换不同的产品族。可扩展性可以轻松添加新的产品族只需增加新的具体工厂和产品类抽象产品而不需要修改现有的代码。
1.1 经典的抽象工厂模式
我们通过生成简单的“示意图”来进行演示这段程序定义了两个工厂一个生成纯文本格式的示意图一个生成SVG格式的示意图。
同时此程序采用了两种写法
diagram1.py按照传统方式来运用抽象工厂模式diagram2.py借助了python的特性使得写出来的程序更短小清晰
下面是diagram1.py的代码结构 代码主要结构的解释如下
有一个create_diagram()的抽象工厂输入参数是具体工厂有两个具体工厂类既是基类也定义了抽象接口(创建图、创建矩形、创建文本)有三个抽象产品Diagram、Rectangle、Text定义了图形、矩阵、文本的具体行为有六个具体产品 DiagramASCII 格式图形 SvgDiagramSVG 格式图形 RectangleASCII 格式矩形 SvgRectangleSVG 格式矩形 TextASCII 格式文本 SvgTextSVG 格式文本 具体产品是抽象产品的实现类是工厂具体生产出来的产品不过由于设置了限制不同系列的产品不能进行混搭。
这样如果想扩展的具体的产品可以直接增加具体产品就行如果想增加新的组建则增加新的抽象产品和具体产品而不用再去修改抽象工厂和具体工厂。
1.2 Python风格的抽象工厂模式
上面的写法演示了传统的抽象工厂模式但是也有几个缺点
SvgDiagramFactory和DiagramFactory的代码几乎一样有很多重复代码两个具体工厂都没有需要初始化的变量所以根本不需要创建实例六个具体产品都放在了“顶级命名空间”中所以为了导致名称冲突只得加上前缀但实际上可以不这样做
下面是diagram1.py的代码结构使用了一些Python的特性让代码变得更简洁:
通过使用classmethod装饰器定义类方法可以来解决这些问题 如上图所示我们把创建图、矩形、文本的方法都嵌套到DiagramFactory中并定义为类方法这样
SvgDiagramFactory只需要继承DiagramFactory即可不需要再去实现那三个方法提升代码简洁性。由于使用了类方法可以直接通过DiagramFactory.make_diagram()来调用不需要再创建一个实例。在SvgDiagramFactory和DiagramFactory中我们都可以使用Diagram、Text、Rectangle去定义类因为他们分别属于SvgDiagramFactory和DiagramFactory下面所以不需要再添加前缀此时“顶级命名空间”中只剩下了create_Ddagram()、DiagramFactory、SvgDiagramFactory
2 建造者模式
也叫生成器模式、构建者模式与抽象工厂类似都可以创建由其他对象组合而成的复杂对象但建造者模式还会保存复杂对象里各个部分的细节。
建造者模式分步骤构造复杂的对象。这种模式的主要目的是将一个复杂对象的构建与其表示分离使得相同的构建过程可以创建不同的表示。建造者模式通常用于需要根据不同的参数组合来创建不同配置的对象场景。
建造者模式的结构
抽象建造者 定义了一个接口规定了所有具体建造者必须实现的方法。具体建造者 继承自 AbstractFormBuilder并提供了具体的实现,每个具体建造者负责构建特定类型的产品导演类: 负责指导构建过程。它接收一个建造者实例并调用建造者的各个方法以逐步构建最终产品它不关心具体是如何构建产品的只负责按照一定的规则或流程调用建造者的方法。
这里通过“表单生成程序“来演示这段程序可以生成一个HTML的表单和一个Tkinter的GUI表单代码文件是formbuilder.py:
有一个抽象建造者AbstractFormBuilder定义了如 add_title(), form(), add_label(), add_entry(), 和 add_button() 方法这些方法定义了构建过程中的步骤。有两个具体建造HtmlFormBuilder 和 TkFormBuilder分别是继承自AbstractFormBuilder并且根据各自的场景对方法进行了重写。有一个导演类create_login_form指出了构造流程如下 builder参数是指HtmlFormBuilder()或者TkFormBuilder()main()函数也只负责“指挥”导演类进行搭建
优点
灵活性与可扩展性: 建造者模式使得代码更加灵活和易于扩展。如果需要添加新的表单类型只需要创建一个新的具体建造者类然后在main()中选择使用它即可。控制复杂性: 它隐藏了对象创建的具体细节使main()代码更加简洁可以更改产品的内部结构而不影响其他代码
3 工厂方法模式
这个模式的核心思想是定义一个用于创建对象的接口但由子类决定实例化哪一个类。这样工厂方法让类的实例化推迟到子类。这种模式的主要优点是它遵循了开闭原则Open/Closed Principle即软件实体对扩展开放对修改关闭。通过使用工厂方法模式你可以在不修改现有代码的情况下引入新的产品类型。
工厂方法模式的结构
Product产品接口 定义所有具体产品类的公共接口。客户端代码使用这个接口来操作具体的对象而无需关心具体的实现细节。Concrete Product具体产品 实现了Product接口的具体类。每个具体产品代表一个可以被创建的对象。Creator创建者/抽象工厂 包含了一个或多个工厂方法用于声明创建Product对象的接口。它通常是一个抽象类定义了工厂方法但没有实现它Concrete Creator具体创建者/具体工厂 继承自Creator并实现了工厂方法以返回一个特定类型的Concrete Product实例。
以gameboard4.py为例 产品接口是Piece类 具体产品是通过 exec 动态创建的类继承自 Piece 类。如下图代码 LAbstractBoard 类是创建者它定义了 populate_board() 抽象方法子类需要实现此方法来创建具体的棋子。 heckersBoard 和 ChessBoard 类分别是具体创建者它们继承自 AbstractBoard并且实现了 populate_board() 方法来具体创建棋子并将其放置到棋盘上。
优点
提高代码可扩展性 例如在这段代码中若想增加新的棋子类型如“象棋”中的“炮”棋子只需要新增一个新的棋子类和相应的创建方法而不需要修改棋盘类的其他部分。提供了灵活的产品替换机制 比如如果要从国际象棋变更为跳棋只需要在 CheckersBoard 类中调整 populate_board 方法而不需要修改整个代码结构。符合开放封闭原则 例如假如我们要添加一个新的棋类游戏如围棋我们只需要新建一个围棋棋盘类并实现相关的工厂方法来生成围棋棋子而现有的国际象棋和跳棋代码不会受到影响。
4 原型模式
原型模式通过复制现有的对象来创建新对象而不是通过构造函数来直接创建新对象。它的核心思想是使用“原型”对象作为模板复制它来创建新的对象这种方式可以提高性能尤其是在创建复杂对象时避免了重复的初始化工作。
关键概念
原型Prototype 一个可以被复制的对象它包含了创建其他相似对象的能力。克隆Clone 通过复制原型对象来创建新的对象。通常原型类提供一个 clone() 方法来完成这个任务。浅拷贝与深拷贝 浅拷贝 仅复制对象的基本类型属性复杂类型的属性如列表、对象等仍然指向原对象中的同一引用。 深拷贝 复制对象及其所有子对象完全独立于原对象。
原型模式的结构
Prototype原型 声明一个 clone() 方法用于复制当前对象。ConcretePrototype具体原型 实现 clone() 方法复制当前对象的所有属性并返回一个新的对象实例。Client客户端 使用原型对象通过调用 clone() 方法来获得新的对象。
示例代码
import copy# 1. 原型类提供 clone 方法
class Prototype:def clone(self):# 默认浅拷贝return copy.copy(self)# 2. 具体原型类
class ConcretePrototype(Prototype):def __init__(self, name, age):self.name nameself.age agedef __str__(self):return f{self.name}, {self.age}def clone(self):# 这里进行深拷贝return copy.deepcopy(self)# 3. 客户端代码
def main():original ConcretePrototype(Alice, 30)print(Original:, original)# 使用原型模式创建副本clone1 original.clone()print(Clone1:, clone1)# 修改副本的属性确保原型不受影响clone1.name Bobclone1.age 25print(Modified Clone1:, clone1)print(Original after modifying Clone1:, original)if __name__ __main__:main()
Prototype 类是一个抽象类定义了 clone() 方法具体的原型类需要实现这个方法来复制对象。在 ConcretePrototype 中clone() 方法使用了 copy.deepcopy() 来实现深拷贝这样我们得到的副本对象与原始对象完全独立不会相互影响。
优点
如果某些对象的创建过程比较复杂且多个地方需要相似的对象可以通过原型模式来减少重复工作。如果需要在运行时创建大量相似的对象可以通过原型模式来提高性能。如果产品有多种不同变体但这些变体之间有相似的结构可以通过原型模式来共享公共部分。
5 单例模式
单例模式确保一个类只有一个实例并提供全局访问点来获取这个实例。该模式主要用于限制类的实例化次数保证系统中某个类始终只有一个实例适用于那些只需要一个共享资源或全局配置的场景。
关键特性
唯一性 确保类只有一个实例。全局访问点 提供全局访问该实例的方式。懒加载 实例仅在第一次使用时创建而不是一开始就创建。
6 总结
介绍了5种创建型设计模式其中
单例模式可以用Python的模块来实现没有特别的地方。由于Python可以动态的访问类对象所以原型模式也什么意义python提供了内置的copy方法所以最有用的是抽象工厂模式、工厂方法模式、建造者模式