37游戏平台,张家界seo网站优化,东莞市研发网站建设企业,如何自己做网站建设这些模式关注对象之间的组合和关联方式#xff0c;以便形成更大的结构和功能。 适配器模式#xff08;Adapter Pattern#xff09;桥接模式#xff08;Bridge#xff09;装饰器模式#xff08;Decorator#xff09;组合模式#xff08;Composite#xff09;外观模式以便形成更大的结构和功能。 适配器模式Adapter Pattern桥接模式Bridge装饰器模式Decorator组合模式Composite外观模式Facade享元模式Flyweight代理模式Proxy 适配器模式Adapter Pattern
将一个类的接口转换成客户端所期望的另一个接口。 这种模式通常用于解决两个不兼容接口之间的兼容性问题。充电线的转接头的功能
一个生活中的实例是使用适配器模式连接不同类型的电源插头和电源插座。假设你有一个美国制造的电器它使用美国标准的两脚插头Type A而你的墙上只有中国标准的三脚插座Type I。为了让电器能够在中国使用你需要一个适配器来连接两者。 以下是一个简单的代码示例展示了如何使用适配器模式来连接不同类型的插头和插座
# 目标接口
class SocketAdapter:def __init__(self, plug):self.plug plugdef connect(self):pass# 中国标准插座
class ChinaSocket:def connect_china_socket(self):print(连接中国标准插座)# 美国标准插头
class USPlug:def connect_us_plug(self):print(连接美国标准插头)# 适配器类
class ChinaToUSAdapter(SocketAdapter):def connect(self):self.plug.connect_china_socket()# 客户端代码
if __name__ __main__:china_socket ChinaSocket()adapter ChinaToUSAdapter(china_socket)adapter.connect()在上述代码中我们定义了一个目标接口 SocketAdapter它声明了一个 connect 方法。然后我们有一个中国标准插座类 ChinaSocket它具有一个 connect_china_socket 方法用于连接中国标准插座。
接下来我们有一个美国标准插头类 USPlug它具有一个 connect_us_plug 方法用于连接美国标准插头。
然后我们创建了一个适配器类 ChinaToUSAdapter它继承了目标接口 SocketAdapter。适配器类内部持有一个中国标准插座对象 china_socket并实现了目标接口的 connect 方法该方法通过适配器调用中国标准插座的连接方法。
最后我们在客户端代码中创建了中国标准插座对象 china_socket并将其传递给适配器类的构造函数创建适配器对象 adapter。然后我们调用适配器对象的 connect 方法它会通过适配器调用中国标准插座的连接方法。
通过适配器模式我们可以使用适配器对象连接不同类型的插头和插座使得它们能够兼容并正常工作。这样我们就实现了不同类型的插头和插座之间的兼容性。
桥接模式Bridge
把抽象化与实现化解耦
# 桥接模式的实现# 实现部分的接口
class DrawingAPI:def draw_circle(self, x, y, radius):pass# 具体实现部分A
class DrawingAPIA(DrawingAPI):def draw_circle(self, x, y, radius):print(f在坐标({x}, {y})处以半径{radius}绘制圆形使用实现A)# 具体实现部分B
class DrawingAPIB(DrawingAPI):def draw_circle(self, x, y, radius):print(f在坐标({x}, {y})处以半径{radius}绘制圆形使用实现B)# 抽象部分
class Shape:def __init__(self, drawing_api):self.drawing_api drawing_apidef draw(self):pass# 具体抽象部分1
class CircleShape(Shape):def __init__(self, x, y, radius, drawing_api):super().__init__(drawing_api)self.x xself.y yself.radius radiusdef draw(self):self.drawing_api.draw_circle(self.x, self.y, self.radius)# 具体抽象部分2
class SquareShape(Shape):def __init__(self, x, y, side_length, drawing_api):super().__init__(drawing_api)self.x xself.y yself.side_length side_lengthdef draw(self):self.drawing_api.draw_square(self.x, self.y, self.side_length)# 客户端代码
if __name__ __main__:circle_a CircleShape(1, 2, 3, DrawingAPIA())circle_a.draw()circle_b CircleShape(4, 5, 6, DrawingAPIB())circle_b.draw()在这个示例中我们使用了桥接模式来将抽象部分Shape和实现部分DrawingAPI解耦。抽象部分定义了基本的形状如圆形和正方形而实现部分定义了具体的绘制方法。 通过将抽象部分和实现部分组合在一起我们可以轻松地在运行时选择不同的实现而无需更改抽象部分的代码。这样可以实现更灵活和可扩展的代码结构。 在上述示例中我们创建了两个具体的实现部分DrawingAPIA 和 DrawingAPIB它们分别用于绘制圆形。然后我们创建了两个具体的抽象部分CircleShape分别使用不同的实现部分进行绘制。
如果不使用桥接模式进行解耦代码可能会变得更加紧密耦合具体实现部分将直接嵌入到抽象部分中。以下是一个示例展示了没有使用桥接模式的情况
# 没有使用桥接模式的紧密耦合示例# 圆形类
class CircleShape:def __init__(self, x, y, radius):self.x xself.y yself.radius radiusdef draw(self):# 在这里直接实现绘制圆形的逻辑print(f在坐标({self.x}, {self.y})处以半径{self.radius}绘制圆形)# 正方形类
class SquareShape:def __init__(self, x, y, side_length):self.x xself.y yself.side_length side_lengthdef draw(self):# 在这里直接实现绘制正方形的逻辑print(f在坐标({self.x}, {self.y})处以边长{self.side_length}绘制正方形)# 客户端代码
if __name__ __main__:circle CircleShape(1, 2, 3)circle.draw()square SquareShape(4, 5, 6)square.draw()在这个紧密耦合的示例中绘制逻辑直接嵌入到了具体的抽象部分类中。这导致了以下问题
如果需要修改绘制逻辑例如更改绘制圆形的方式就需要直接修改 CircleShape 类的代码而不是通过更改实现部分来实现。添加新的形状类例如三角形需要在每个具体形状类中重复实现绘制逻辑造成代码重复。
因此使用桥接模式可以将抽象部分和实现部分解耦提高代码的灵活性和可扩展性。它允许我们在运行时选择不同的实现部分而无需修改抽象部分的代码。
装饰器模式Decorator
在不修改原始对象的情况下动态地添加额外的功能。 装饰器模式通过将对象包装在一个具有相同接口的装饰器对象中来实现。
装饰器模式由以下几个关键角色组成
抽象组件Component定义了被装饰对象和装饰器对象的公共接口。具体组件ConcreteComponent实现了抽象组件接口并定义了需要被装饰的对象。抽象装饰器Decorator继承或实现了抽象组件接口并持有一个对抽象组件的引用。它的主要目的是为了扩展或修改抽象组件的行为。具体装饰器ConcreteDecorator实现了抽象装饰器接口并扩展了抽象组件的行为。具体装饰器可以在调用被装饰对象的方法之前或之后添加额外的逻辑。
# 抽象组件
class Component:def operation(self):pass# 具体组件
class ConcreteComponent(Component):def operation(self):print(执行具体组件操作)# 抽象装饰器
class Decorator(Component):def __init__(self, component):self.component componentdef operation(self):self.component.operation()# 具体装饰器
class ConcreteDecorator(Decorator):def operation(self):super().operation()self.additional_operation()def additional_operation(self):print(执行额外的操作)# 客户端代码
if __name__ __main__:# 创建具体组件component ConcreteComponent()# 创建具体装饰器并将具体组件作为参数传递decorator ConcreteDecorator(component)# 执行操作decorator.operation()在上述示例中Component 是抽象组件ConcreteComponent 是具体组件。Decorator 是抽象装饰器ConcreteDecorator 是具体装饰器。客户端代码创建了一个具体组件对象并将其作为参数传递给具体装饰器对象。装饰器对象在调用具体组件对象的方法之前或之后添加了额外的操作。
装饰器模式的优点是可以动态地添加功能而不需要修改原始对象的代码。它提供了一种灵活的方式来扩展对象的行为同时遵循开闭原则。然而装饰器模式可能会导致类的数量增加并且在多层装饰的情况下可能会变得复杂。因此在使用时需要权衡利弊并根据具体需求进行设计和实现。
组合模式Composite
将对象组合成树形结构以表示“部分-整体”的层次结构。 组合模式使得用户可以统一对待单个对象和组合对象从而简化了代码的使用和维护。
组合模式由以下几个关键角色组成
组件Component定义组合中对象的通用接口可以是抽象类或接口。该接口声明了操作方法例如添加、删除、获取子组件等。叶子节点Leaf表示组合中的叶子对象它没有子组件。实现组件接口的具体类。组合节点Composite表示组合中的容器对象它可以包含子组件。实现组件接口的具体类并包含一个集合来存储子组件。客户端Client通过组件接口操作组合对象。
# 组件接口
class Component:def add(self, component):passdef remove(self, component):passdef get_child(self, index):passdef operation(self):pass# 叶子节点
class Leaf(Component):def operation(self):print(执行叶子节点操作)# 组合节点
class Composite(Component):def __init__(self):self.children []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def get_child(self, index):return self.children[index]def operation(self):print(执行组合节点操作)for child in self.children:child.operation()# 客户端代码
if __name__ __main__:# 创建叶子节点leaf1 Leaf()leaf2 Leaf()# 创建组合节点并添加叶子节点composite1 Composite()composite1.add(leaf1)composite1.add(leaf2)# 创建叶子节点leaf3 Leaf()# 创建组合节点并添加叶子节点和组合节点composite2 Composite()composite2.add(leaf3)composite2.add(composite1)# 执行操作composite2.operation()在上述示例中Component 是组件接口Leaf 是叶子节点类Composite 是组合节点类。客户端代码创建了一棵树形结构包含了叶子节点和组合节点并通过调用 operation() 方法执行操作。组合节点会递归调用其子组件的操作方法从而实现整个树形结构的操作。
组合模式的优点是简化了代码的使用和维护使得客户端可以统一对待单个对象和组合对象。它也提供了灵活性和可扩展性因为可以轻松地添加新的叶子节点或组合节点。然而组合模式可能会增加系统的复杂性并且在某些情况下可能会导致性能问题因此在使用时需要权衡利弊。
外观模式Facade
提供了一个统一的接口用于访问子系统中的一组接口。 外观模式隐藏了子系统的复杂性为客户端提供了一个简单的接口来与子系统进行交互。
下面是一个外观模式的示例代码
# 子系统类A
class SubsystemA:def operation_a(self):print(执行子系统A的操作)# 子系统类B
class SubsystemB:def operation_b(self):print(执行子系统B的操作)# 子系统类C
class SubsystemC:def operation_c(self):print(执行子系统C的操作)# 外观类
class Facade:def __init__(self):self.subsystem_a SubsystemA()self.subsystem_b SubsystemB()self.subsystem_c SubsystemC()def operation(self):self.subsystem_a.operation_a()self.subsystem_b.operation_b()self.subsystem_c.operation_c()# 客户端代码
facade Facade()
facade.operation()在上述代码中有三个子系统类 SubsystemA、SubsystemB 和 SubsystemC它们分别提供了各自的操作。外观类 Facade 将这些子系统进行了封装并提供了一个统一的接口 operation()。
在客户端代码中我们创建了一个外观对象 facade然后通过调用 facade.operation() 来访问子系统的操作。在内部外观对象会依次调用子系统类的相应方法隐藏了子系统的复杂性。
当我们执行 facade.operation() 时会依次输出
执行子系统A的操作
执行子系统B的操作
执行子系统C的操作这样客户端就可以通过简单的接口来访问子系统的功能而不需要了解和处理子系统的复杂逻辑。外观模式帮助简化了系统的使用和维护。
享元模式Flyweight
通过共享对象来减少内存使用和提高性能。 享元模式适用于存在大量相似对象的场景通过共享这些对象的内部状态来减少对象的数量。
下面是一个在模具设计中使用享元模式的示例代码
# 模具接口
class Mold:def __init__(self, mold_type):self.mold_type mold_typedef produce(self, product):print(f生产 {product} 使用 {self.mold_type} 模具)# 享元工厂类
class MoldFactory:def __init__(self):self.molds {}def get_mold(self, mold_type):if mold_type not in self.molds:self.molds[mold_type] Mold(mold_type)return self.molds[mold_type]# 客户端代码
mold_factory MoldFactory()# 第一批产品使用 A 类型模具
mold_a mold_factory.get_mold(A)
mold_a.produce(产品1)
mold_a.produce(产品2)# 第二批产品使用 B 类型模具
mold_b mold_factory.get_mold(B)
mold_b.produce(产品3)
mold_b.produce(产品4)# 第三批产品继续使用 A 类型模具
mold_a.produce(产品5)
mold_a.produce(产品6)在上述代码中Mold 类表示模具每个模具有一个类型mold_type属性并且可以生产产品。MoldFactory 类是享元工厂类用于创建和管理模具对象。
在客户端代码中我们通过 MoldFactory 获取模具对象。如果请求的模具对象已经存在于享元工厂中则直接返回该对象否则创建一个新的模具对象并添加到享元工厂中。这样相同类型的模具对象会被共享使用。
在示例中我们先获取了一个类型为 “A” 的模具对象并使用它生产了两个产品。然后我们获取了一个类型为 “B” 的模具对象并使用它生产了两个产品。最后我们又使用之前获取的 “A” 类型模具对象生产了两个产品。
运行上述代码会输出以下结果
生产 产品1 使用 A 模具
生产 产品2 使用 A 模具
生产 产品3 使用 B 模具
生产 产品4 使用 B 模具
生产 产品5 使用 A 模具
生产 产品6 使用 A 模具可以看到尽管我们只创建了两个不同类型的模具对象但通过共享对象的方式成功地减少了模具对象的数量。享元模式帮助我们节省了内存开销并提高了系统的性能。
代理模式Proxy
它提供了一个代理对象控制对另一个对象的访问。 通过使用代理对象可以在访问对象时添加额外的逻辑例如权限控制、缓存、延迟加载等。
下面是一个代理模式的示例代码
# 主题接口
class Subject:def request(self):pass# 真实主题类
class RealSubject(Subject):def request(self):print(处理真实请求)# 代理类
class Proxy(Subject):def __init__(self, real_subject):self.real_subject real_subjectdef request(self):# 在访问真实主题前添加额外的逻辑self.pre_request()# 调用真实主题的请求方法self.real_subject.request()# 在访问真实主题后添加额外的逻辑self.post_request()def pre_request(self):print(代理对象处理请求前的操作)def post_request(self):print(代理对象处理请求后的操作)# 客户端代码
real_subject RealSubject()
proxy Proxy(real_subject)# 通过代理对象访问真实主题
proxy.request()在上述代码中有一个主题接口 Subject其中定义了一个 request() 方法。RealSubject 类是真实主题类实现了主题接口并提供了具体的请求处理逻辑。
Proxy 类是代理类也实现了主题接口并持有一个真实主题对象。在代理类的 request() 方法中可以在调用真实主题对象的请求方法前后添加额外的逻辑。在示例中我们在访问真实主题前后分别输出了一些操作。
在客户端代码中我们创建了一个真实主题对象 real_subject然后将其传递给代理对象 proxy 的构造函数。通过代理对象 proxy我们可以访问真实主题的请求方法。
当执行 proxy.request() 时会依次输出
代理对象处理请求前的操作
处理真实请求
代理对象处理请求后的操作可以看到代理对象在访问真实主题前后添加了额外的操作。代理模式帮助我们控制对真实主题的访问并可以在访问前后进行一些附加处理。这样我们可以在不修改真实主题代码的情况下对其进行扩展和增强。