Skip to content

Commit 098a327

Browse files
committed
Bridge: add structural example
1 parent 79cd5e2 commit 098a327

3 files changed

Lines changed: 142 additions & 1 deletion

File tree

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[pycodestyle]
22
count = True
3-
ignore = W293
3+
ignore = W293,W605
44
max-line-length = 200
55

66
[pep8]

src/Bridge/Structure/Output.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Abstraction: Base operation with:
2+
ConcreteImplementationA: Here's the result on the platform A.
3+
4+
ExtendedAbstraction: Extended operation with:
5+
ConcreteImplementationB: Here's the result on the platform B.

src/Bridge/Structure/main.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"""
2+
EN: Bridge Design Pattern
3+
4+
Intent: Decouple an abstraction from its implementation so that the two can
5+
vary independently.
6+
7+
A
8+
/ \ A N
9+
Aa Ab ===> / \ / \
10+
/ \ / \ Aa(N) Ab(N) 1 2
11+
Aa1 Aa2 Ab1 Ab2
12+
13+
RU: Паттерн Мост
14+
15+
Назначение: Разделяет абстракцию и реализацию, что позволяет изменять их
16+
независимо друг от друга.
17+
18+
A
19+
/ \ A N
20+
Aa Ab ===> / \ / \
21+
/ \ / \ Aa(N) Ab(N) 1 2
22+
Aa1 Aa2 Ab1 Ab2
23+
"""
24+
25+
26+
from __future__ import annotations
27+
from abc import ABC, abstractmethod
28+
29+
30+
class Abstraction:
31+
"""
32+
EN: The Abstraction defines the interface for the "control" part of the two
33+
class hierarchies. It maintains a reference to an object of the
34+
Implementation hierarchy and delegates all of the real work to this object.
35+
36+
RU: Абстракция устанавливает интерфейс для «управляющей» части двух иерархий
37+
классов. Она содержит ссылку на объект из иерархии Реализации и делегирует
38+
ему всю настоящую работу.
39+
"""
40+
41+
def __init__(self, implementation: Implementation):
42+
self.implementation = implementation
43+
44+
def operation(self) -> str:
45+
return f"Abstraction: Base operation with:\n{self.implementation.operation_implementation()}"
46+
47+
48+
class ExtendedAbstraction(Abstraction):
49+
"""
50+
EN: You can extend the Abstraction without changing the Implementation
51+
classes.
52+
53+
RU: Можно расширить Абстракцию без изменения классов Реализации.
54+
"""
55+
56+
def operation(self) -> str:
57+
return f"ExtendedAbstraction: Extended operation with:\n{self.implementation.operation_implementation()}"
58+
59+
60+
class Implementation(ABC):
61+
"""
62+
EN: The Implementation defines the interface for all implementation classes.
63+
It doesn't have to match the Abstraction's interface. In fact, the two
64+
interfaces can be entirely different. Typically the Implementation interface
65+
provides only primitive operations, while the Abstraction defines higher-
66+
level operations based on those primitives.
67+
68+
RU: Реализация устанавливает интерфейс для всех классов реализации. Он не
69+
должен соответствовать интерфейсу Абстракции. На практике оба интерфейса
70+
могут быть совершенно разными. Как правило, интерфейс Реализации
71+
предоставляет только примитивные операции, в то время как Абстракция
72+
определяет операции более высокого уровня, основанные на этих примитивах.
73+
"""
74+
75+
@abstractmethod
76+
def operation_implementation(self) -> str:
77+
pass
78+
79+
80+
"""
81+
EN: Each Concrete Implementation corresponds to a specific platform and
82+
implements the Implementation interface using that platform's API.
83+
84+
RU: Каждая Конкретная Реализация соответствует определённой платформе и
85+
реализует интерфейс Реализации с использованием API этой платформы.
86+
"""
87+
88+
89+
class ConcreteImplementationA(Implementation):
90+
def operation_implementation(self) -> str:
91+
return "ConcreteImplementationA: Here's the result on the platform A."
92+
93+
94+
class ConcreteImplementationB(Implementation):
95+
def operation_implementation(self) -> str:
96+
return "ConcreteImplementationB: Here's the result on the platform B."
97+
98+
99+
def client_code(abstraction: Abstraction) -> None:
100+
"""
101+
EN: Except for the initialization phase, where an Abstraction object gets
102+
linked with a specific Implementation object, the client code should only
103+
depend on the Abstraction class. This way the client code can support any
104+
abstraction-implementation combination.
105+
106+
RU: За исключением этапа инициализации, когда объект Абстракции связывается с
107+
определённым объектом Реализации, клиентский код должен зависеть только от
108+
класса Абстракции. Таким образом, клиентский код может поддерживать любую
109+
комбинацию абстракции и реализации.
110+
"""
111+
112+
# ...
113+
114+
print(abstraction.operation(), end="")
115+
116+
# ...
117+
118+
119+
if __name__ == "__main__":
120+
"""
121+
EN: The client code should be able to work with any pre-configured
122+
abstraction-implementation combination.
123+
124+
RU: Клиентский код должен работать с любой предварительно сконфигурированной
125+
комбинацией абстракции и реализации.
126+
"""
127+
128+
implementation = ConcreteImplementationA()
129+
abstraction = Abstraction(implementation)
130+
client_code(abstraction)
131+
132+
print("\n")
133+
134+
implementation = ConcreteImplementationB()
135+
abstraction = ExtendedAbstraction(implementation)
136+
client_code(abstraction)

0 commit comments

Comments
 (0)