Python设计模式 - 适配器模式

Python设计模式 - 适配器模式,第1张

'''

适配器模式:将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

应用场景:希望复用一些现存的类,但是接口又与复用环境要求不一致。

分类:类适配器(通过多重继承)、对象适配器。

'''

class Dog(object):

    def __init__(self):

        self.name = "Dog"

    def bark(self):

        return "汪!"

class Cat(object):

    def __init__(self):

        self.name = "Cat"

    def meow(self):

        return "喵!"

class Human(object):

    def __init__(self):

        self.name = "Human"

    def speak(self):

        return "'你好'"

class Car(object):

    def __init__(self):

        self.name = "Car"

    def make_noise(self, octane_level):

        return "引擎声{0}".format("!" * octane_level)

class Adapter(object):

    def __init__(self, obj, **adapted_methods):

        """我们对象字典里设置适配的方法"""

        self.obj = obj

        '''update()方法添加键 - 值对到字典'''

        self.__dict__.update(adapted_methods)

    """我们可以通过重载__getattr__和__setattr__来拦截对成员的访问或者作出一些自己希望的行为

     __getattr__ 在访问对象访问类中不存在的成员时会自动调用"""

    def __getattr__(self, attr):

        return getattr(self.obj, attr ,'没有找到此属性')

    def original_dict(self):

        """输出对象的实例属性"""

        return self.obj.__dict__

def main():

    """定义一个空对象列表"""

    objects = []

    dog = Dog()

    print(dog.__dict__)

    '''追加Adapter实例对象到列表'''

    objects.append(Adapter(dog, make_noise=dog.bark))

    '''Adapter实例属性, 实例也有一个 __dict__特殊属性,它是实例属性构成的一个字典:'''

    '''__dict__ 返回的是一个字典,它的键(key)是属性名,键值(value)是相应的属性对象的数据值'''

    '''实例仅拥有数据属性,它是与某个类的实例相关联的数据值,这些值独立于其他实例或类。当一个实例被释放后,它的属性同时也被清除了。'''

    print(objects[0].__dict__)

    print(objects[0].original_dict())

    print(objects[0].QQ)

    print(objects[0].make_noise())

    print("-----------------------------------------------")

    cat = Cat()

    objects.append(Adapter(cat, make_noise=cat.meow))

    print(objects[1].__dict__)

    print("-----------------------------------------------")

    human = Human()

    objects.append(Adapter(human, make_noise=human.speak))

    print(objects[2].__dict__)

    print("-----------------------------------------------")

    car = Car()

    objects.append(Adapter(car, make_noise=lambda: car.make_noise(5)))

    print(objects[3].__dict__)

    print("-----------------------------------------------")

    for obj in objects:

        print("一个 {0} 正在 {1}".format(obj.name, obj.make_noise()))

if __name__ == "__main__":

        main()

网上看到不少关于适配器模式的讲解,其中对于适配器模式解释的过于专业,一时不是特别理解适配器模式到底是用来干嘛的,具体的适用场景在哪,其最精髓的地方到底在哪。

本文结合自己的理解,阐述下对适配器模式的看法。

假设系统存在一个现有的类UserInfo:

客户端可以通过如下方式set、get员工基本信息:

有一天,基于某种原因(也许你看着这种取数据的方式不太爽,也许是系统间数据交换的原因等),你需要按照如下接口的方式取数据:

目标员工接口:

那么,现在的问题是,如何将一个既定的类转换成按照目标接口的所期望的行为形式呢?

具体怎样实现呢,可以通过如下方式进行:

从上面的UserAdapter类定义中我们发现,UserAdapter不仅实现了UserInterface接口,同时还继承了UserInfo类。在实现接口的getName()和getTelNumber()方法中,分别调用了UserInfo类中的相应方法并取得结果。由此可以满足需求。在上述定义中,按照UserInterface、UserInfo和UserAdapter在场景中的目的不同,可以具体划分成如下角色:

UserInterface:目标角色——目标接口,系统所期待实现的目标;

UserInfo:源角色——当前已经存在的原有的实现类,即将被适配的类;

UserAdapter:适配器角色——将原有实现装换为目标接口的实现。

简单点说,适配器模式是指: 定义一个类,将一个已经存在的类,转换成目标接口所期望的行为形式

在具体的实现过程中,又可以基于其实现层次是类层次还是对象层次,将其分为类适配器和对象适配器。如上所写的是类适配器。

对象适配器使用组合代替继承,将源角色视为适配器角色的属性:

总体而言:适配器模式是指定义一个适配器类,将一个已经存在的类,转换成目标接口所期望的行为形式。同时,一般来说,基于更多的推荐使用组合而不是继承,因此,对象适配器可能使用更多。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/7984016.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存