首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

python设计模式-外观模式

上一篇

《python设计模式-适配器模式》

介绍了如何将一个类的接口转换成另一个符合期望的接口。这一篇将要介绍需要一个为了简化接口而改变接口的新模式-外观模式(Facade-Pattern)。

问题

:如果你组装了一套家庭影院,内含播放器、投影机、自动屏幕、立体声音响、爆米花机等。如何设计一个遥控器,可以简单的操作这个系统中的各个组件呢?首先来看一下最笨方式观赏电影的步骤:

打开爆米花机

开始爆米花

将灯光调暗

放下屏幕

打开投影仪

将投影机的输入切换到播放器

将投影及设置在宽屏模式

打开功放

将功放的输入设置为播放器

将攻防设置为环绕立体声

将攻防音量调到适中

打开播放器

播放电影

写成类和方法的调用大概是以下的样子:

# 打开爆米花机,开始爆米花

poper.on()

poper.pop()

# 灯光调暗

lights.dim(10)

# 放下屏幕

screen.down()

# 打开投影仪,设置为宽屏模式

projector.on()

projector.setInput(dvd)

projector.wideScreenMode()

# 打开功放 设置为DVD 调整成环绕立体声模式,音量调到5

amp.on()

amp.setDvd(dvd)

amp.setSurroundSound()

amp.setVolume(5)

# 打开dvd 播放器

dvd.on()

dvd.play(movie)

可以看到代码中涉及到6个不同的类,而且电影看完后还需要回退,一切都要再反着重来一遍。怎样简化一下操作呢?现在,外观模式就可以大展身手了。使用外观模式,可以通过实现一个提供更合理的接口的外观类,将子系统变得更容易使用。当然,原来的接口还在。

解决方法

先来看一下外观模式如何运作

这里为家庭影院系统创建了一个新的外观类,这个类暴露出来几个简单的方法,比如,。

这个外观类将家庭影院的多个组件看作一个子系统,通过调用这个子系统来实现方法。

外观只提供了一个更直接的操作方式,并没有将原来的子系统隔离,子系统的功能还可以使用

1. 可以有多个外观2. 外观提供简化的接口,但不隔离子系统3. 外观将实现从子系统中解耦,比如:现在有个子系统的组件需要升级换代,只需要把外观代码做相应的修改就可以实现4. 外观和适配器都可以包装多个类,但是,而。

示例

classHomeTheaterFacade(object):

#先声明需要用的子组件

amp=Amplifier()

tuner=Tuner()

dvd=DvdPlayer()

cd=CdPlayer()

projector=Projector()

lights=TheaterLights()

screen=Screen()

popper=PopcornPopper()

defwatchMovie(self,movie):

# watchMovie 将之前需要手动处理的任务批量处理

print("Get ready to watch a movie...")

# 打开爆米花机,开始爆米花

self.poper.on()

self.poper.pop()

# 灯光调暗

self.lights.dim(10)

# 放下屏幕

self.screen.down()

# 打开投影仪,设置为宽屏模式

self.projector.on()

self.projector.setInput(dvd)

self.projector.wideScreenMode()

# 打开功放 设置为DVD 调整成环绕立体声模式,音量调到5

self.amp.on()

self.amp.setDvd(dvd)

self.amp.setSurroundSound()

self.amp.setVolume(5)

# 打开dvd 播放器

self.dvd.on()

self.dvd.play(movie)

defendMovie(self):

# endMovie 负责关闭一切,由子系统中的组件完成

print("Shutting movie theater down...")

self.popper.off()

self.lights.on()

self.screen.up()

self.projector.off()

self.amp.off()

self.dvd.stop()

self.dvd.eject()

self.dvd.off()

代码使用

defmain():

home_theater=HomeTheaterFacade()# 实例化外观

home_theater.watchMovice()# 使用简化方法开启 关闭电影ß

home_theater.endMovice()

定义

外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

从类图也可以了解到,外观模式的主要意图是提供一个更简单易用的接口。最少知识原则(least Knowledge)的意思是减少对象之间的交互,只和几个特定的对象交互。这个原则是希望在设计中,不要耦合太多的类,以免修改系统时,会影响到其它部分。比如:如果想从DVD播放器获取音响的音量,可以在Dvd播放器中加入一个方法,用来像音响请求当前音量,而不是先返回音响对象,再从音响对象返回音量。

# 不好的实践

defget_volume():

tuner=dvd.tuner()

returntuner.get_volume

# 好的实践

defget_volume():

# 这里要给dvd 对象加一个get_volume方法

returndvd.get_volume

虽然这个原则减少了对象之间的依赖,但是也会导致更多的包装被制造出来(比如上边例子中,就需要给方法),这也可能会导致系统更复杂。再回顾一下外观模式的例子,会发现外观模式符合,客户端只有这一个交互对象。它的存在让系统调用变的更简单,并且如果需要子系统有模块需要升级,只需要修改这个类就可以完成升级。本文例子来自《Head First 设计模式》。最后,感谢女朋友支持和包容,比❤️也可以在公号输入以下关键字获取历史文章:||

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181125G17PUL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券