Als Material zum Erlernen von GoF-Entwurfsmustern scheint das Buch "Einführung in Entwurfsmuster, die in der erweiterten und überarbeiteten Java-Sprache gelernt wurden" hilfreich zu sein. Da die aufgeführten Beispiele jedoch auf JAVA basieren, habe ich dieselbe Vorgehensweise mit Python versucht, um mein Verständnis zu vertiefen.
Das Brückenmuster (Brückenmuster) ist eines der von GoF (Gang of Four; 4 Banden) definierten Entwurfsmuster. Der Zweck besteht darin, die Klasse in mehrere Richtungen zu erweitern, indem eine "Brücken" -Klasse vorbereitet wird.
UML class and sequence diagram UML class diagram (Das Obige wird aus Wikipedia zitiert)
Das Bridge-Muster scheint die ** Feature-Class-Hierarchie ** und die ** Implementierungsklassen-Hierarchie ** zu überbrücken.
Wenn Sie einer Klasse neue Funktionen hinzufügen möchten, definieren Sie eine neue Unterklasse und implementieren Sie die Methode. Die Beziehung zwischen einer vorhandenen Oberklasse und einer neu definierten Unterklasse ist die "Funktionsklassenhierarchie". Nehmen Sie im Allgemeinen die folgenden Beziehungen an.
Wenn Sie eine neue Implementierung hinzufügen möchten, definieren Sie eine konkrete Unterklasse, die von der abstrakten Klasse abgeleitet ist, und implementieren Sie dann die Methode. Die Beziehung zwischen einer vorhandenen abstrakten Klasse und einer neu abgeleiteten konkreten Unterklasse ist die "Klassenhierarchie der Implementierung". Nehmen Sie im Allgemeinen die folgenden Beziehungen an.
Ich möchte tatsächlich ein Beispielprogramm ausführen, das das Bridge-Muster verwendet, und das folgende Verhalten überprüfen. Dies ist ein Beispiel, das eine Brücke zwischen der ** Funktionsklassenhierarchie ** und der ** Implementierungsklassenhierarchie ** voraussetzt.
$ python Main.py
+-----------+
|Hello Japan|
+-----------+
+-----------+
|Hello Japan|
+-----------+
+--------------+
|Hello Universe|
+--------------+
+--------------+
|Hello Universe|
|Hello Universe|
|Hello Universe|
|Hello Universe|
|Hello Universe|
+--------------+
+--------------+
|Hello Universe|
|Hello Universe|
|Hello Universe|
|Hello Universe|
+--------------+
aaa
bbb
ccc
ddd
eee
fff
ggg
Wenn Sie nur das Beispielprogramm ausführen, wissen Sie nicht wirklich, was Sie tun möchten. Als nächstes überprüfen wir die Details des Beispielprogramms.
Ähnlicher Code wurde in das Git-Repository hochgeladen. https://github.com/ttsubo/study_of_design_pattern/tree/master/Bridge
--Verzeichnisaufbau
.
├── Main.py
├── bridge
│ ├── __init__.py
│ ├── function
│ │ ├── __init__.py
│ │ ├── display_count_func.py
│ │ ├── display_func.py
│ │ └── display_random_func.py
│ └── implement
│ ├── __init__.py
│ ├── display_impl.py
│ ├── display_string_impl.py
│ └── display_textfile_impl.py
└── test.txt
Es ist eine Klasse, die nur grundlegende Funktionen mit der Methode "Implementieren" implementiert. Im Beispielprogramm übernimmt die Klasse "DisplayFunc" diese Rolle.
bridge/function/display_func.py
class DisplayFunc(object):
def __init__(self, impl):
self.impl = impl
def open(self):
self.impl.rawOpen()
def print_body(self):
self.impl.rawPrint()
def close(self):
self.impl.rawClose()
def display(self):
self.open()
self.print_body()
self.close()
Dies ist eine Rolle mit zusätzlichen Funktionen zur Rolle "Abstraktion". Im Beispielprogramm übernehmen die Klasse "DisplayCountFunc" und die Klasse "DisplayRandomFunc" diese Rolle.
bridge/function/display_count_func.py
from bridge.function.display_func import DisplayFunc
class DisplayCountFunc(DisplayFunc):
def __init__(self, impl):
super(DisplayCountFunc, self).__init__(impl)
def multiDisplay(self, times):
self.open()
for _ in range(times):
self.print_body()
self.close()
bridge/function/display_random_func.py
import random
from bridge.function.display_func import DisplayFunc
class DisplayRandomFunc(DisplayFunc):
def __init__(self, impl):
super(DisplayRandomFunc, self).__init__(impl)
def randomDisplay(self, times):
self.open()
t = random.randint(0, times)
for _ in range(t):
self.print_body()
self.close()
Diese Rolle definiert eine Methode zum Implementieren der Schnittstelle der Rolle "Abstraktion". Im Beispielprogramm übernimmt die Klasse "DisplayImpl" diese Rolle.
bridge/implement/display_impl.py
from abc import ABCMeta, abstractmethod
class DisplayImpl(metaclass=ABCMeta):
@abstractmethod
def rawOpen(self):
pass
@abstractmethod
def rawPrint(self):
pass
@abstractmethod
def rawClose(self):
pass
Insbesondere ist es die Rolle der Implementierung der Schnittstelle der Rolle "Implementieren". Im Beispielprogramm übernehmen die Klasse "DisplayStringImpl" und die Klasse "DisplayTextfileImpl" diese Rolle.
bridge/implement/display_string_impl.py
from bridge.implement.display_impl import DisplayImpl
class DisplayStringImpl(DisplayImpl):
def __init__(self, string):
self.string = string
self.width = len(string)
def rawOpen(self):
self.printLine()
def rawPrint(self):
print("|{0}|".format(self.string))
def rawClose(self):
self.printLine()
print("")
def printLine(self):
line = '-' * self.width
print("+{0}+".format(line))
bridge/implement/display_textfile_impl.py
from bridge.implement.display_impl import DisplayImpl
class DisplayTextfileImpl(DisplayImpl):
def __init__(self, filename):
self.filename = filename
def rawOpen(self):
filename = self.filename
self.f = open(filename, "r")
def rawPrint(self):
data = self.f.read()
data = data.split('\n')
for l in data:
print(l)
def rawClose(self):
self.f.close()
Im Beispielprogramm übernimmt die Methode "startMain" diese Rolle.
Main.py
from bridge.function.display_func import DisplayFunc
from bridge.function.display_count_func import DisplayCountFunc
from bridge.function.display_random_func import DisplayRandomFunc
from bridge.implement.display_string_impl import DisplayStringImpl
from bridge.implement.display_textfile_impl import DisplayTextfileImpl
def startMain():
d1 = DisplayFunc(DisplayStringImpl("Hello Japan"))
d2 = DisplayCountFunc(DisplayStringImpl("Hello Japan"))
d3 = DisplayCountFunc(DisplayStringImpl("Hello Universe"))
d4 = DisplayRandomFunc(DisplayStringImpl("Hello Universe"))
d5 = DisplayFunc(DisplayTextfileImpl("test.txt"))
d1.display()
d2.display()
d3.display()
d3.multiDisplay(5)
d4.randomDisplay(5)
d5.display()
if __name__ == '__main__':
startMain()
Recommended Posts