桥接法Python设计模式
桥接方法是一种结构设计模式,它允许我们将实现特定抽象和实现独立抽象相互分离,并且可以将其视为单个实体进行开发。
桥接法一直被认为是组织类层次结构的最佳方法之一。
桥梁设计模式的要素
- 抽象:它是桥接设计模式的核心,为实现者提供参考。
- Refined Abstraction:它将抽象扩展到新的层次,在这个层次上它需要更精细的细节,并对实现者隐藏更精细的元素。
- 实现者:它定义了实现类的接口。这个接口不需要直接对应抽象接口,可以有很大的不同。
- 具体实现:通过具体实现,实现上述实现者。
不使用桥接方法的问题
考虑下面的类Cuboid ,它具有三个属性,分别命名为长度、宽度和高度,以及三个名为ProducewithAPI1()、ProduceWithAPI2()和expand()的方法。
其中,生产方法是特定于实现的,因为我们有两个生产 API 和一个方法,即 expand() 方法是独立于实现的。
到目前为止,我们只有两种特定于实现的方法和一种独立于实现的方法,但是当数量增加时(当然在大型项目中),开发人员处理的事情就会变得一团糟。
注意:以下代码是在不使用 Bridge 方法的情况下编写的。
Python3
""" Code without using the bridge method
We have a class with three attributes
named as length, breadth, and height and
three methods named as ProduceWithAPI1(),
ProduceWithAPI2(), and expand(). Out of these
producing methods are implementation-specific
as we have two production APIs"""
class Cuboid:
class ProducingAPI1:
"""Implementation Specific Implementation"""
def produceCuboid(self, length, breadth, height):
print(f'API1 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
class ProducingAPI2:
"""Implementation Specific Implementation"""
def produceCuboid(self, length, breadth, height):
print(f'API2 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
def __init__(self, length, breadth, height):
"""Initialize the necessary attributes"""
self._length = length
self._breadth = breadth
self._height = height
def produceWithAPI1(self):
"""Implementation specific Abstraction"""
objectAPIone = self.ProducingAPI1()
objectAPIone.produceCuboid(self._length, self._breadth, self._height)
def producewithAPI2(self):
"""Implementation specific Abstraction"""
objectAPItwo = self.ProducingAPI2()
objectAPItwo.produceCuboid(self._length, self._breadth, self._height)
def expand(self, times):
"""Implementation independent Abstraction"""
self._length = self._length * times
self._breadth = self._breadth * times
self._height = self._height * times
# Instantiate a Cubiod
cuboid1 = Cuboid(1, 2, 3)
# Draw it using APIone
cuboid1.produceWithAPI1()
# Instantiate another Cuboid
cuboid2 = Cuboid(19, 20, 21)
# Draw it using APItwo
cuboid2.producewithAPI2()
Python3
"""Code implemented with Bridge Method.
We have a Cuboid class having three attributes
named as length, breadth, and height and three
methods named as produceWithAPIOne(), produceWithAPItwo(),
and expand(). Our purpose is to separate out implementation
specific abstraction from implementation-independent
abstraction"""
class ProducingAPI1:
"""Implementation specific Abstraction"""
def produceCuboid(self, length, breadth, height):
print(f'API1 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
class ProducingAPI2:
"""Implementation specific Abstraction"""
def produceCuboid(self, length, breadth, height):
print(f'API2 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
class Cuboid:
def __init__(self, length, breadth, height, producingAPI):
"""Initialize the necessary attributes
Implementation independent Abstraction"""
self._length = length
self._breadth = breadth
self._height = height
self._producingAPI = producingAPI
def produce(self):
"""Implementation specific Abstraction"""
self._producingAPI.produceCuboid(self._length, self._breadth, self._height)
def expand(self, times):
"""Implementation independent Abstraction"""
self._length = self._length * times
self._breadth = self._breadth * times
self._height = self._height * times
"""Instantiate a cuboid and pass to it an
object of ProducingAPIone"""
cuboid1 = Cuboid(1, 2, 3, ProducingAPI1())
cuboid1.produce()
cuboid2 = Cuboid(19, 19, 19, ProducingAPI2())
cuboid2.produce()
使用 Bridge 方法的解决方案
现在让我们看看上述问题的解决方案。桥接法是此类问题的最佳解决方案之一。我们的主要目的是将实现特定抽象和实现无关抽象的代码分开。
注意:以下代码是使用桥接方法编写的
Python3
"""Code implemented with Bridge Method.
We have a Cuboid class having three attributes
named as length, breadth, and height and three
methods named as produceWithAPIOne(), produceWithAPItwo(),
and expand(). Our purpose is to separate out implementation
specific abstraction from implementation-independent
abstraction"""
class ProducingAPI1:
"""Implementation specific Abstraction"""
def produceCuboid(self, length, breadth, height):
print(f'API1 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
class ProducingAPI2:
"""Implementation specific Abstraction"""
def produceCuboid(self, length, breadth, height):
print(f'API2 is producing Cuboid with length = {length}, '
f' Breadth = {breadth} and Height = {height}')
class Cuboid:
def __init__(self, length, breadth, height, producingAPI):
"""Initialize the necessary attributes
Implementation independent Abstraction"""
self._length = length
self._breadth = breadth
self._height = height
self._producingAPI = producingAPI
def produce(self):
"""Implementation specific Abstraction"""
self._producingAPI.produceCuboid(self._length, self._breadth, self._height)
def expand(self, times):
"""Implementation independent Abstraction"""
self._length = self._length * times
self._breadth = self._breadth * times
self._height = self._height * times
"""Instantiate a cuboid and pass to it an
object of ProducingAPIone"""
cuboid1 = Cuboid(1, 2, 3, ProducingAPI1())
cuboid1.produce()
cuboid2 = Cuboid(19, 19, 19, ProducingAPI2())
cuboid2.produce()
桥接法的UML图
下面是桥接方法的 UML 图
好处
- 单一职责原则:桥接方法显然遵循单一职责原则,因为它将抽象与其实现分离,以便两者可以独立变化。
- Open/Closed 原则:它不违反 Open/Closed 原则,因为在任何时候我们都可以相互独立地引入新的抽象和实现
- 平台独立特性:桥接方法可以很容易地用于实现平台独立特性。
缺点
- 复杂性:应用Bridge 方法后,我们的代码可能会变得复杂,因为我们正在侵入新的抽象类和接口。
- 双重间接:桥接方法可能会对性能产生轻微的负面影响,因为抽象需要与实现一起传递消息才能执行操作。
- 只有一个实现的接口:如果我们只有有限的接口,那么它不会出汗,但是如果你有一组爆炸的接口,只有一个实现,或者只有一个实现,就很难管理
适用性
- 运行时绑定:一般Bridge方法用于提供实现的运行时绑定,这里的运行时绑定是指我们可以在运行时而不是编译时调用方法。
- 映射类: Bridge 方法用于映射正交类层次结构
- UI 环境:在 UI 环境中定义形状时使用了 Bridge 方法的实际应用
进一步阅读: Java中的桥接方法