深度定制化,啥都能做的委托模式

2021-01-08 15:24:31 浏览数 (1)

点击上方蓝字,关注并星标,和我一起学技术。

大家好,今天我们来介绍一个很简单但是也很牛的设计模式——委托模式

举个例子

在我们介绍具体的代码之前,我们先来设想一个场景。假设说你成了某知名电商某一个重要首页板块的负责人,你希望这个板块推荐的商品内容更加丰富,不仅包含推荐系统的结果,也包含一些商家付费的广告结果,还能有一些运营配置的活动结果。

这个例子不是我空穴来风,而是现在主流的电商公司其实都是这么做的。比如下图淘宝的猜你喜欢,虽然这是一个典型的推荐展位,但是其中的商品却未必都来自推荐系统,可能有一些是广告,还有一些是运营配置的活动。

一个展位有三种数据源头其实不是问题,问题是由于历史遗留原因,可能这三种系统各自的接口格式不一样。不一样带来的问题是,整合这些数据的逻辑必须要硬编码,而无法做到配置化。如果数据来源越来越多,这样硬编码的规则也就随之增加,这必然会导致日后的维护成本迅速提升。

我们今天要介绍的委托模式正是为了解决这个问题,它可以将底层的接口进行封装,使得上层在调用的时候,可以规约到一个接口。

代码实现

说起来委托模式牛哄哄,好像很厉害的样子。但其实代码很简单,一看大家就明白了。

代码语言:javascript复制
class Delegator:

    def __init__(self, delegate):
        self.delegate = delegate

    def __getattr__(self, name):
        attr = getattr(self.delegate, name, None)

        if attr is None:
            return ''

        if not callable(attr): 
            return attr

        def wrapper(*args, **kwargs):
            return attr(*args, **kwargs)

        return wrapper

    def interface(self, name, *args, **kwargs):
        attr = getattr(self.delegate, name, None)

        if attr is None:
            return ''

        if not callable(attr): 
            return attr

        return attr(*args, **kwargs)


class Delegate:

    def __init__(self):
        self.p1 = 123

    def do_something(self, something):
        return 'Doing %s' % something

    
if __name__ == '__main__':
    delegator = Delegator(Delegate())
    print(delegator.p1)

    print(delegator.do_something('nothing'))
    print(delegator.interface('do_something', 'search result'))
    print(delegator.interface('do_something', 'ads result'))

这里Delegate将自己的功能委托给了Delegator,我们直接对Delegator调用Delegate的功能,或者是调用Deletagor的接口传入对应的参数,就可以调用到Delegate的方法。

这当中的逻辑也非常简单,我们使用了Python内置的getattr方法,它可以获取实例的某一个属性。如果是其他静态类型的语言,可能需要通过反射等操作才可以实现类似的功能,不得不说Python虽然运行效率低了不少,但是很多应用还是很强大的。

这个设计模式虽然简单,但是用处却不小,在很多场景上使用出来会大大简化代码的复杂度,也可以更加了解Python的一些特性。

今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、在看、转发

0 人点赞