基于Python学习《Head First设计模式》第七章 适配器和外观模式

适配器模式

了解适配器


简单示例

python 复制代码
class Duck(ABC):
    """鸭子"""

    @abstractmethod
    def quack(self):
        pass

    @abstractmethod
    def fly(self):
        pass


class MallardDuck(Duck):
    """绿头鸭"""

    def quack(self):
        print("Quack")

    def fly(self):
        print("I'm flying")


class Turkey(ABC):
    """火鸡"""

    @abstractmethod
    def gobble(self):
        pass

    @abstractmethod
    def fly(self):
        pass
python 复制代码
class WildTurkey(Turkey):
    """野鸡"""

    def gobble(self):
        print('Gobble gobble')

    def fly(self):
        print("I'm flying a short distance")


class TurkeyAdapter(Duck):
    turkey: Turkey

    def __init__(self, turkey: Turkey):
        self.turkey = turkey

    def quack(self):
        self.turkey.gobble()

    def fly(self):
        for _ in range(5):
            self.turkey.fly()
python 复制代码
if __name__ == '__main__':
    duck = MallardDuck()
    turkey = WildTurkey()
    turkey_adapter = TurkeyAdapter(turkey)
    print('The Turkey says...')
    turkey.gobble()
    turkey.fly()

    print('\nThe Duck says...')
    duck.quack()
    duck.fly()

    print('\nThe TurkeyAdapter says...')
    turkey_adapter.quack()
    turkey_adapter.fly()

完整代码

python 复制代码
from abc import ABC, abstractmethod


class Duck(ABC):
    """鸭子"""

    @abstractmethod
    def quack(self):
        pass

    @abstractmethod
    def fly(self):
        pass


class MallardDuck(Duck):
    """绿头鸭"""

    def quack(self):
        print("Quack")

    def fly(self):
        print("I'm flying")


class Turkey(ABC):
    """火鸡"""

    @abstractmethod
    def gobble(self):
        pass

    @abstractmethod
    def fly(self):
        pass


class WildTurkey(Turkey):
    """野鸡"""

    def gobble(self):
        print('Gobble gobble')

    def fly(self):
        print("I'm flying a short distance")


class TurkeyAdapter(Duck):
    turkey: Turkey

    def __init__(self, turkey: Turkey):
        self.turkey = turkey

    def quack(self):
        self.turkey.gobble()

    def fly(self):
        for _ in range(5):
            self.turkey.fly()


class DuckAdapter(Turkey):
    duck: Duck

    def __init__(self, duck: Duck):
        self.duck = duck
        self.__reset()

    def __reset(self):
        self.rand = (_ for _ in range(4))

    def gobble(self):
        self.duck.quack()

    def fly(self):
        try:
            next(self.rand)
        except StopIteration:
            self.duck.fly()
            self.__reset()


if __name__ == '__main__':
    duck = MallardDuck()
    turkey = WildTurkey()
    turkey_adapter = TurkeyAdapter(turkey)
    duck_adapter = DuckAdapter(duck)
    print('The Turkey says...')
    turkey.gobble()
    turkey.fly()

    print('\nThe Duck says...')
    duck.quack()
    duck.fly()

    print('\nThe TurkeyAdapter says...')
    turkey_adapter.quack()
    turkey_adapter.fly()

    print('\nThe DuckAdapter says...')
    duck_adapter.gobble()
    for _ in range(10):
        duck_adapter.fly()

"""运行结果:
The Turkey says...
Gobble gobble
I'm flying a short distance

The Duck says...
Quack
I'm flying

The TurkeyAdapter says...
Gobble gobble
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance

The DuckAdapter says...
Quack
I'm flying
I'm flying
"""

适配器模式解析

适配器 包装一个被适配者

适配器定义

类适配器 VS 对象适配器



对象适配器可以适配一个被适配者类类适配器只能针对特定的被适配者类
举例: 对象适配器使用组合的方式,可以适配整个Duck类,而类适配器用继承只能支配Duck的具体类,比如绿头鸭类。

但子类类添加新的行为时,类适配器更胜一筹。

外观模式

项目:家庭影院



代码实现

python 复制代码
class HomeTheaterFacade:
    """家庭影院外观"""
    amp: Amplifier
    tunner: Tunner
    player: StreamingPlayer
    projector: Projector
    lights: TheaterLights
    screen: Screen
    popper: PopcornPopper

    def __init__(self, amp: Amplifier, tunner: Tunner,
                 player: StreamingPlayer,
                 projector: Projector,
                 lights: TheaterLights,
                 screen: Screen,
                 popper: PopcornPopper):
        self.amp = amp
        self.tunner = tunner
        self.player = player
        self.projector = projector
        self.lights = lights
        self.screen = screen
        self.popper = popper
python 复制代码
    def watch_movie(self,movie:str):
        print('准备播放电影...')
        self.popper.on()
        self.popper.pop()
        self.lights.lim(10)
        self.screen.down()
        self.projector.on()
        self.projector.wideScrennMode()
        self.amp.on()
        self.amp.setStreamingPlayer(self.player)
        self.amp.setSurroundSound()
        self.amp.setVolume(5)
        self.player.on()
        self.player.play(movie)
        
    def end_movie(self):
        print('停止播放电影')
        self.popper.off()
        self.lights.on()
        self.screen.up()
        self.projector.off()
        self.amp.off()
        self.player.stop()
        self.player.off()
python 复制代码
if __name__ == '__main__':
    amp = Amplifier()
    tunner = Tunner()
    player = StreamingPlayer()
    projector = Projector()
    lights = TheaterLights()
    screen = Screen()
    popper = PopcornPopper()

    home_theater = HomeTheaterFacade(amp, tunner, player, projector, lights, screen, popper)
    home_theater.watch_movie('傲慢与偏见')
    print()
    home_theater.end_movie()

完整代码

python 复制代码
class Amplifier:
    """扩音器"""

    def on(self):
        print('打开扩音器')

    def setStreamingPlayer(self, player):
        print('设置流媒体输入')

    def setSurroundSound(self):
        print('设置环绕音响')

    def setVolume(self, param):
        print(f'设置音量为{param}')

    def off(self):
        print('关闭扩音器')


class Tunner:
    pass


class StreamingPlayer:
    """流媒体播放器"""

    def on(self):
        print('打开流媒体播放器')

    def play(self, movie):
        print(f'播放{movie}')

    def stop(self):
        print('停止播放')

    def off(self):
        print('关闭流媒体播放器')


class Projector:
    """投影机"""

    def on(self):
        print('打开投影机')

    def wideScrennMode(self):
        print('设置投影机为宽屏模式')

    def off(self):
        print('关闭投影机')


class TheaterLights:
    """影院灯光"""

    def lim(self, param):
        print('调暗灯光')

    def on(self):
        print('打开灯光')


class PopcornPopper:
    """爆米花机器"""

    def on(self):
        print('打开爆米花机器')

    def pop(self):
        print('提供爆米花')

    def off(self):
        print('关闭爆米花机器')


class Screen:
    """投影机的屏幕"""

    def down(self):
        print('放下屏幕')

    def up(self):
        print('收起屏幕')


class HomeTheaterFacade:
    """家庭影院外观"""
    amp: Amplifier
    tunner: Tunner
    player: StreamingPlayer
    projector: Projector
    lights: TheaterLights
    screen: Screen
    popper: PopcornPopper

    def __init__(self, amp: Amplifier, tunner: Tunner,
                 player: StreamingPlayer,
                 projector: Projector,
                 lights: TheaterLights,
                 screen: Screen,
                 popper: PopcornPopper):
        self.amp = amp
        self.tunner = tunner
        self.player = player
        self.projector = projector
        self.lights = lights
        self.screen = screen
        self.popper = popper

    def watch_movie(self, movie: str):
        print('准备播放电影...')
        self.popper.on()
        self.popper.pop()
        self.lights.lim(10)
        self.screen.down()
        self.projector.on()
        self.projector.wideScrennMode()
        self.amp.on()
        self.amp.setStreamingPlayer(self.player)
        self.amp.setSurroundSound()
        self.amp.setVolume(5)
        self.player.on()
        self.player.play(movie)

    def end_movie(self):
        print('停止播放电影')
        self.popper.off()
        self.lights.on()
        self.screen.up()
        self.projector.off()
        self.amp.off()
        self.player.stop()
        self.player.off()


if __name__ == '__main__':
    amp = Amplifier()
    tunner = Tunner()
    player = StreamingPlayer()
    projector = Projector()
    lights = TheaterLights()
    screen = Screen()
    popper = PopcornPopper()

    home_theater = HomeTheaterFacade(amp, tunner, player, projector, lights, screen, popper)
    home_theater.watch_movie('傲慢与偏见')
    print()
    home_theater.end_movie()

"""运行结果:
准备播放电影...
打开爆米花机器
提供爆米花
调暗灯光
放下屏幕
打开投影机
设置投影机为宽屏模式
打开扩音器
设置流媒体输入
设置环绕音响
设置音量为5
打开流媒体播放器
播放傲慢与偏见

停止播放电影
关闭爆米花机器
打开灯光
收起屏幕
关闭投影机
关闭扩音器
停止播放
关闭流媒体播放器
"""

外观模式定义

适配器模式 VS 外观模式

适配器 的意图是:转化修改接口以匹配客户的期望。
外观模式 的意图是:简化,提供子系统的一个简化的接口

总结

相关推荐
lyaihao4 分钟前
使用python实现奔跑的线条效果
python·绘图
恰薯条的屑海鸥5 分钟前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习
喜欢吃燃面33 分钟前
C++刷题:日期模拟(1)
c++·学习·算法
ai大师40 分钟前
(附代码及图示)Multi-Query 多查询策略详解
python·langchain·中转api·apikey·中转apikey·免费apikey·claude4
小小爬虾1 小时前
关于datetime获取时间的问题
python
2301_797604242 小时前
学习记录:DAY32
学习
蓝婷儿2 小时前
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
开发语言·python·学习
叶子2024222 小时前
学习使用YOLO的predict函数使用
人工智能·学习·yolo
jackson凌3 小时前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
chao_7893 小时前
链表题解——两两交换链表中的节点【LeetCode】
数据结构·python·leetcode·链表