结构型模式主要处理对象之间的关系,通过继承、组合等方式实现对象的适用性、功能性、易用性以及性能方面的需求。主要包括适配器模式、修饰器模式、外观模式、享元模式、MVC模式、代理模式等。

1. 适配器模式

适配器模式主要用于解决接口兼容性问题。实际业务中的场景也很多,比如对接不同支付接口,新系统支持旧系统的数据等。在Python中,通过 sqlalchemy 模块可以直接对接不同数据库,也是一种适配器的例子。

适配器的一种实现方式是在适配器类中进行类型转换,也就是说,实际调用的是另一个类:

class Backend:
def complain(self):
print(“前端就一行代码的事”)
class Frontend:
def argue(self):
print(“请后端改下接口”)
class FrontendAdapter(Backend):
frontend = Frontend()
def complain(self):
self.frontend.argue()

《精通Python设计模式》中,利用Python的特性提供了另一种实现方式。

在Python中,对象的属性是保存在__dict__字典中的,实例调用属性或方法时,会先查自己的__dict__字典,再根据方法解析顺序,逐级往上,查找类的字典或者父类的字典。

而Python中的函数也是一等对象,可以当做参数随意传递,因此,只需要把实例的方法保存在适配器的__dict__字典中,就可以优先调用了。

根据这种思路,可以按如下方式实现一个适配器:

class Programer:
def __init__(self, obj, adapted_methods):
self.obj = obj
# 更新实例字典,用新名称保存要调用的方法
self.__dict__.update(adapted_methods)
backend, frontend = Backend(), Frontend()
programers = [
Programer(backend, dict(meeting=backend.complain)),
Programer(frontend, dict(meeting=frontend.argue))
]
while True:
for p in programers:
p.meeting()

这种方式看上去要优雅多了。

2. 修饰器模式

修饰器模式主要用于功能的组合或扩展,比较常见的是用来实现切面需求。

“切面需求”和“面向对象”的概念有点互补的意思。比如不同的对象,执行不同的方法,可能都需要记录日志,测试性能,使用缓存等,就可以调用统一的方法来实现。用现实中的例子类比的话,可能近似于公司里的行政、人事部门,其它部门都需要调用他们提供的基本服务。

Python内置了装饰器特性,可调用对象可以通过装饰器特性进行快速的功能扩展。所谓可调用对象,就是可以在它后面加“()”进行调用,即实现了__call__方法的对象,比如类和函数。如果某类对象实现了__call__方法,则这个类的实例也是可调用的。

这样,Python中的装饰器使用就非常灵活了,装饰器本身可以是一个类或一个函数,被装饰对象也可以是一个类或一个函数,或者其它的可调用对象。

关于Python装饰器的使用,网上已经有了足够多的文章。如果有需要,个人推荐这篇:理解 Python 装饰器看这一篇就够了foofish.net

这里就不多讨论了。

当我们在自己的项目中看到重复的代码,而这些代码所实现的是切面需求时,很有可能就要考虑加一个装饰器了。

未完待续……

END