适配器是在后期用来使不相关的类一起工作的,而桥接模式则是在前期设计将实现与它的抽象部分解耦。
真实世界的例子
如今,信息产品或infoproduct是人们可以在网上找到的资源的一部分,用于培训、自我提高、或自己的想法和业务发展。你在某些市场上找到的信息产品,或供应商的网站,其目的是以一种易于获取和消费的方式提供关于特定主题的信息。所提供的材料可以是PDF文件或电子书、视频、在线课程、基于订阅的通讯,或所有这的组合。
在软件领域,设备驱动经常被引为桥的例子开发者为设备供应商定义接口来实现它。
应用
当你想在多个对象之间共享实现时,可以定义以下的特殊组件。
- 适用于所有类的抽象概念
- 适用于所涉及的不同对象的单独接口
实例
让我们假设我们正在建立一个应用程序,用户将在从不同的来源获取内容后对其进行管理和交付,这些来源可能是。
- 网页(根据其URL)。
- FTP服务器上访问的资源
- 本地文件
- 数据库服务器
我们可以为资源内容定义一个抽象,为负责获取内容的对象定义一个单独的接口,而不是实现几个内容类,每个类都有负责获取内容的方法,并将它们组装起来。
class ResourceContent:
"""
Define the abstraction's interface.
Maintain a reference to an object which represents the Implementor.
"""
def __init__(self, imp):
self._imp = imp
def show_content(self, path):
self._imp.fetch(path)
我们使用Python语言的两个特性,即元类特性(帮助定义类型的类型)和抽象基类(ABC)来定义相当于Python中的接口。
class ResourceContentFetcher(metaclass=abc.ABCMeta):
"""
Define the interface (Implementor) for implementation classes that help fetch content.
"""
@abc.abstractmethod
def fetch(path):
pass
添加实现类来获取网页或资源中的内容。
class URLFetcher(ResourceContentFetcher):
"""
Implement the Implementor interface and define its concrete
implementation.
"""
def fetch(self, path):
# path is an URL
req = urllib.request.Request(path)
with urllib.request.urlopen(req) as response:
if response.code == 200:
the_page = response.read()
print(the_page)
class LocalFileFetcher(ResourceContentFetcher):
"""
Implement the Implementor interface and define its concrete
implementation.
"""
def fetch(self, path):
# path is the filepath to a text file
with open(path) as f:
print(f.read())
小结
在本章中,我们讨论了桥接模式。桥接模式与适配器模式有相似之处,但与之不同的是,桥接模式是在前期用解耦的方式来定义一个抽象和它的实现,因此两者可以独立变化。
在为操作系统和设备驱动、GUI和网站建设者等问题领域编写软件时,桥接模式非常有用,因为我们有多个主题,需要根据某些属性来改变网站的主题。
为了帮助你理解这种模式,我们讨论了内容提取和管理领域的一个例子,我们定义了抽象接口,以及两个实现。
网友评论