Apprenez le modèle de conception "Bridge" avec Python

En tant que matériel d'apprentissage des modèles de conception du GoF, le livre «Introduction aux modèles de conception appris dans le langage Java augmenté et révisé» semble être utile. Cependant, comme les exemples repris sont basés sur JAVA, j'ai essayé la même pratique avec Python pour approfondir ma compréhension.

■ Pont (modèle de pont)

Le modèle de pont (modèle de pont) est l'un des modèles de conception définis par le GoF (Gang of Four; 4 gangs). Le but est d'étendre la classe dans plusieurs directions en préparant une classe «pontage».

UML class and sequence diagram W3sDesign_Bridge_Design_Pattern_UML.jpg UML class diagram bridge.png (Ce qui précède est cité sur Wikipedia)

□ Mémorandum

Le modèle Bridge semble établir un pont entre la ** hiérarchie des classes d'entités ** et la ** hiérarchie des classes d'implémentation **.

(1) Quelle est la hiérarchie des classes de fonctions?

Si vous souhaitez ajouter de nouvelles fonctionnalités à une classe, définissez une nouvelle sous-classe et implémentez la méthode. La relation entre une superclasse existante et une sous-classe nouvellement définie est la "hiérarchie des classes fonctionnelles". En général, supposez les relations suivantes.

--Super classe a des fonctions de base

(2) Quelle est la hiérarchie des classes d'implémentation?

Si vous souhaitez ajouter une nouvelle implémentation, définissez une sous-classe concrète dérivée de la classe abstraite, puis implémentez la méthode. La relation entre une classe abstraite existante et une sous-classe concrète nouvellement dérivée est la "hiérarchie de classes d'implémentation". En général, supposez les relations suivantes.

--Dans la classe abstraite, l'interface est définie par la méthode abstraite.

■ Exemple de programme "Bridge"

Je voudrais exécuter un exemple de programme qui utilise le modèle Bridge et vérifier le comportement suivant. Il s'agit d'un exemple qui suppose un pont entre la ** hiérarchie de classes de fonctions ** et la ** hiérarchie de classes d'implémentation **.

$ 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

Si vous exécutez simplement l'exemple de programme, vous ne savez pas vraiment ce que vous voulez faire. Ensuite, vérifions les détails de l'exemple de programme.

■ Détails de l'exemple de programme

Un code similaire a été téléchargé dans le référentiel Git. https://github.com/ttsubo/study_of_design_pattern/tree/master/Bridge

.
├── 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

(1) Le rôle de l'abstraction

Cette classe implémente uniquement les fonctions de base en utilisant la méthode de ʻImplement. Dans l'exemple de programme, la classe DisplayFunc` remplit ce rôle.

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()

(2) Le rôle de l'abstraction raffinée

ʻAbstractionC'est un rôle avec des fonctions supplémentaires. Dans l'exemple de programme, la classeDisplayCountFunc et la classe DisplayRandomFunc` remplissent ce rôle.

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()

(3) Le rôle du réalisateur

ʻAbstractionC'est le rôle qui définit la méthode d'implémentation de l'interface de rôle. Dans l'exemple de programme, la classeDisplayImpl` remplit ce rôle.

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

(4) Le rôle du réalisateur concret

Plus précisément, c'est le rôle d'implémentation de l'interface du rôle de ʻImplement. Dans l'exemple de programme, la classe DisplayStringImpl et la classe DisplayTextfileImpl` remplissent ce rôle.

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()

(5) Le rôle du client

Dans l'exemple de programme, la méthode startMain remplit ce rôle.

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()

■ URL de référence

Recommended Posts

Apprenez le modèle de conception "Bridge" avec Python
Apprenez le modèle de conception "Prototype" avec Python
Apprenez le modèle de conception "Flyweight" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Proxy" en Python
Apprenez le modèle de conception "Commande" en Python
Apprenez le modèle de conception "Visiteur" avec Python
Apprenez le modèle de conception "Mediator" avec Python
Apprenez le modèle de conception "Décorateur" avec Python
Apprenez le modèle de conception "Iterator" avec Python
Apprenez le modèle de conception «Stratégie» avec Python
Apprenez le modèle de conception "Composite" avec Python
Apprenez le modèle de conception "État" en Python
Apprenez le modèle de conception "Adapter" avec Python
Apprenez le modèle de conception "Abstract Factory" avec Python
Apprenez le modèle de conception "Méthode de modèle" en Python
Apprenez le modèle de conception "Méthode d'usine" en Python
Apprenez le modèle de conception «Chaîne de responsabilité» en Python
Apprenez le modèle de conception "Singleton" avec Python
Apprenez le modèle de conception "Façade" avec Python
Implémenter le modèle Singleton en Python
Motif singleton en Python
Modèle de visiteur en Python
Trouver des erreurs en Python
Modèles de conception en Python: introduction
Python Design Pattern - Méthode de modèle
Obtenir l'API arXiv en Python
Python dans le navigateur: la recommandation de Brython
Frappez l'API Sesami en Python
Obtenez le chemin du bureau en Python
Obtenez le chemin du script en Python
Dans la commande python, python pointe vers python3.8
Accédez à l'API Web en Python
J'ai écrit la file d'attente en Python
Calculer le mois précédent en Python
Examiner la classe d'un objet avec python
Obtenez le chemin du bureau en Python
Obtenez le nom d'hôte en Python
Accéder à l'API Twitter avec Python
La première étape de Python Matplotlib
J'ai écrit la pile en Python
Maîtriser le module lowref en Python
Apprenez les bases de Python ① Débutants élémentaires
Charger le SDK Python distant avec IntelliJ
Essayez d'utiliser l'API Wunderlist en Python
[Python Kivy] À propos de la modification du thème de conception
Essayez d'utiliser l'API Kraken avec Python
Apprenez les bases en touchant les variables python
Ecrire le test dans la docstring python
Prenez la somme logique de List en Python (fonction zip)
Afficher Python 3 dans le navigateur avec MAMP
Tweet à l'aide de l'API Twitter en Python
Vérifiez si l'URL existe en Python
Associez l'ensemble de tables dans les modèles de python.py
Exécuter l'interpréteur Python dans le script
Le résultat de l'installation de python sur Anaconda
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
Lisez le fichier ligne par ligne avec Python