适配器模式
了解适配器
简单示例

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 外观模式
适配器 的意图是:转化
,修改接口
以匹配客户的期望。
外观模式 的意图是:简化
,提供子系统的一个简化的接口
。
总结
