适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
适用场景:
优点:
缺点:
from abc import abstractmethod, ABCMeta
class OldLogger:
"""
抽象化角色
"""
def debug(self, msg):
print(f"旧的日志器:{msg}")
class NewLogger:
def new_debug(self, msg):
print(f"新的日志器:{msg}")
class AdapterLogger(OldLogger):
def __init__(self, logger: NewLogger):
self.logger = logger
def debug(self, msg):
self.logger.new_debug(msg)
def main(log: OldLogger):
log.debug("调试中")
if __name__ == "__main__":
logger = AdapterLogger(NewLogger())
main(logger)
桥接模式就是把抽象部分与实现部分抽离,使其可以匹配多种组合
说白了就是将俩种不同维度的事物进行任意组合使用,防止产生笛卡尔积
为什么要使用桥接模式
商城系统中常见的商品分类,以电脑分类为例,我们可以使用多层继承结构
假设加上一个品牌,荣耀,那么我们就需要再创建一个品牌抽象,实现3个分类。一个两个还好,如果添加100个种类呢?就会发生类爆炸(类贼多),后期维护复杂,违反单一职责原则。
桥接模式结构
桥,顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来,而这两个被联系起来的结构可以独立的变化。而实现桥接模式的具体操作就是将抽象化部分与实现化部分分开,取消二者的继承关系,改用组合关系,并用桥连接
代码示例
from abc import abstractmethod, ABCMeta
class AbstractPen(metaclass=ABCMeta):
"""
抽象化角色
"""
def __init__(self, shape):
self.shape = shape # 对实现化对象的引用
@abstractmethod
def draw(self):
raise NotImplementedError
class GreenPen(AbstractPen):
"""
扩展抽象化角色:绿色笔
"""
def draw(self):
print("我用绿色画笔,", end='')
self.shape.draw()
class RedPen(AbstractPen):
"""
扩展抽象化角色:红色笔
"""
def draw(self):
print("我用红色画笔,", end='')
self.shape.draw()
class AbstractShape(metaclass=ABCMeta):
"""
实现化角色
"""
@abstractmethod
def draw(self):
raise NotImplementedError
class Circle(AbstractShape):
"""
具体实现化角色:圆形
"""
def draw(self):
print("圆形")
class Rectangle(AbstractShape):
"""
具体实现化角色:矩形
"""
def draw(self):
print("矩形")
if __name__ == "__main__":
RedPen(Rectangle()).draw()
优点:
缺点:
class Customer:
def __init__(self, name, gender, age, address):
self.name = name
self.gender = gender
self.age = age
self.address = address
class Filter:
def execute(self, customers):
pass
class GenderFilter(Filter):
def __init__(self, gender):
self.gender = gender
def execute(self, customers):
result = []
for customer in customers:
if customer.gender == self.gender:
result.append(customer)
return result
class AgeFilter(Filter):
def __init__(self, min_age, max_age):
self.min_age = min_age
self.max_age = max_age
def execute(self, customers):
result = []
for customer in customers:
if self.min_age <= customer.age <= self.max_age:
result.append(customer)
return result
class AddressFilter(Filter):
def __init__(self, address):
self.address = address
def execute(self, customers):
result = []
for customer in customers:
if customer.address == self.address:
result.append(customer)
return result
class CustomerDataAnalysis:
def __init__(self, customers):
self.customers = customers
def apply_filter(self, filter_obj):
filtered_customers = filter_obj.execute(self.customers)
return filtered_customers
if __name__ == '__main__':
customers = [
Customer("Tom", "Male", 27, "Beijing"),
Customer("Jerry", "Male", 32, "Shanghai"),
Customer("Lucy", "Female", 24, "Guangzhou"),
Customer("Lily", "Female", 38, "Shenzhen"),
Customer("Jack", "Male", 29, "Beijing"),
]
analysis = CustomerDataAnalysis(customers)
result = analysis.apply_filter(GenderFilter("Male"))
print("Male Customers:")
for customer in result:
print(customer.name)
result = analysis.apply_filter(AgeFilter(25, 35))
print("Customers between 25 and 35 years old:")
for customer in result:
print(customer.name)
result = analysis.apply_filter(AddressFilter("Shanghai"))
print("Customers from Shanghai:")
for customer in result:
print(customer.name)
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
from abc import ABC, abstractmethod
class Component(ABC):
def __init__(self, name):
self.name = name
@abstractmethod
def operation(self, depth):
pass
@abstractmethod
def add(self, c):
pass
@abstractmethod
def remove(self, c):
pass
@abstractmethod
def get_child(self, index):
pass
class Composite(Component):
def __init__(self, name):
Component.__init__(self, name)
self.children = []
def operation(self, depth):
strtemp = ''
for i in range(depth):
strtemp += strtemp+'-'
print(strtemp+self.name)
for comp in self.children:
comp.operation(depth+2)
def add(self, c):
self.children.append(c)
def remove(self, c):
self.children.remove(c)
def get_child(self, index):
return self.children[index]
class Leaf(Component):
def operation(self, depth):
strtemp = ''
for i in range(depth):
strtemp += strtemp+'-'
print(strtemp+self.name)
def add(self, c):
print('不能添加下级节点!')
def remove(self, c):
print('不能删除下级节点!')
def get_child(self, index):
print('没有下级节点!')
class Client:
@staticmethod
def main():
# 生成树根
root = Composite("root")
# 根上长出2个叶子
root.add(Leaf('leaf A'))
root.add(Leaf('leaf B'))
# 根上长出树枝Composite X
comp = Composite("Composite X")
comp.add(Leaf('leaf XA'))
comp.add(Leaf('leaf XB'))
root.add(comp)
# 根上长出树枝Composite X
comp2 = Composite("Composite XY")
# Composite X长出2个叶子
comp2.add(Leaf('leaf XYA'))
comp2.add(Leaf('leaf XYB'))
root.add(comp2)
# 根上又长出2个叶子,C和D,D没长好,掉了
root.add(Leaf('Leaf C'))
leaf = Leaf("Leaf D")
root.add(leaf)
root.remove(leaf)
# 展示组织
root.operation(1)
if __name__ == '__main__':
Client.main()
装饰器模式(Decorator Pattern)允许向一个现有的对象扩展新的功能,同时不改变其结构。主要解决直接继承下因功能的不断横向扩展导致子类膨胀的问题,无需考虑子类的维护。
from abc import abstractmethod, ABCMeta
class IMilktea(metaclass=ABCMeta):
"""
抽象构件(Component)角色:奶茶
"""
@abstractmethod
def add_dosing(self): ...
class PearlMilktea(IMilktea):
"""
具体构件(ConcreteComponent)角色:珍珠奶茶
"""
def add_dosing(self):
print("开始制作:珍珠奶茶")
class LemonMilktea(IMilktea):
"""
具体构件(ConcreteComponent)角色:柠檬水奶茶
"""
def add_dosing(self):
print("开始制作:柠檬水")
class Dosing(IMilktea):
"""
装饰(Decorator)角色:配料
"""
def __init__(self, imilk_tea: IMilktea):
self.imilk_tea = imilk_tea
def add_dosing(self):
self.imilk_tea.add_dosing()
class Pearl(Dosing):
"""
具体装饰(ConcreteDecorator)角色
"""
def add_dosing(self):
super(Pearl, self).add_dosing()
print("制作中:加珍珠")
class Mango(Dosing):
"""
具体装饰(ConcreteDecorator)角色
"""
def add_dosing(self):
super(Mango, self).add_dosing()
print("制作中:加芒果")
if __name__ == "__main__":
tea = PearlMilktea()
tea = Pearl(tea)
tea = Mango(tea)
tea.add_dosing()
Python 外观模式是一种常见的设计模式,它提供了一种简单的方式来组合多个复杂的子系统,使其对外表现为一个简单的接口。
class SubSystemA:
def method_a(self):
print("SubSystemA method_a() called.")
class SubSystemB:
def method_b(self):
print("SubSystemB method_b() called.")
class SubSystemC:
def method_c(self):
print("SubSystemC method_c() called.")
class Facade:
def __init__(self):
self._subsystem_a = SubSystemA()
self._subsystem_b = SubSystemB()
self._subsystem_c = SubSystemC()
def operation(self):
self._subsystem_a.method_a()
self._subsystem_b.method_b()
self._subsystem_c.method_c()
class Client:
def __init__(self):
self._facade = Facade()
def run(self):
self._facade.operation()
client = Client()
client.run()
Python 享元模式是一种优化性的设计模式,它通过共享对象来减少系统中的对象数量,从而提高了系统的性能。该模式的核心思想是将大量的细粒度对象共享,使得系统中实际存在的对象数量极少。
享元模式有两个主要角色:
class Flyweight:
def __init__(self, shared_state):
self._shared_state = shared_state
def operation(self, unique_state):
print(f"Flyweight: Displaying shared ({self._shared_state}) and unique ({unique_state}) state.")
class FlyweightFactory:
def __init__(self):
self._flyweights = {}
def get_flyweight(self, shared_state):
if shared_state not in self._flyweights:
self._flyweights[shared_state] = Flyweight(shared_state)
return self._flyweights[shared_state]
def list_flyweights(self):
print(f"FlyweightFactory: I have {len(self._flyweights)} flyweights:")
for key in self._flyweights.keys():
print(key)
if __name__ == "__main__":
factory = FlyweightFactory()
flyweight1 = factory.get_flyweight("state_1")
flyweight1.operation("unique_1")
flyweight2 = factory.get_flyweight("state_2")
flyweight2.operation("unique_2")
flyweight3 = factory.get_flyweight("state_1")
flyweight3.operation("unique_3")
factory.list_flyweights()
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的代理对象,以控制对原有对象的访问。
使用场景,按职责来划分,通常有以下使用场景:
优点
1、职责清晰。 2、高扩展性。 3、智能化。
缺点
代码示例
import abc
class BaseStation(abc.ABC):
@abc.abstractmethod
def create_tickets(self, start, end): ...
class TrainStation(BaseStation):
"""
火车站
"""
def create_tickets(self, start, end):
print(f"打印从{start}-{end}车票一张")
class ProxyPoint(BaseStation):
"""
代售点
"""
def __init__(self):
self.__train_station = TrainStation()
def create_tickets(self, start, end):
print('通过代售点')
self.__train_station.create_tickets(start, end)
if __name__ == '__main__':
proxy = ProxyPoint()
proxy.create_tickets('nanjing', 'beijing')