Apprenez le modèle de conception "Composite" 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.

■ Composite (motif composite)

Le modèle composite (modèle composite) est l'un des modèles de conception définis par le GoF (Gang of Four; 4 gangs). Il appartient au "modèle structurel". Le modèle composite peut être utilisé pour représenter des structures de données récursives avec des arborescences, telles que des répertoires et des fichiers. Les objets qui apparaissent dans le modèle composite sont des «branches» et des «feuilles», qui implémentent une interface commune. Par conséquent, il y a un avantage que les branches et les feuilles peuvent être manipulées de la même manière.

UML class and object diagram W3sDesign_Composite_Design_Pattern_UML.jpg UML class diagram composite.png (Ce qui précède est cité sur Wikipedia)

□ Mémorandum

Ceci est une citation du livre "Introduction aux modèles de conception appris en langage Java", mais j'avais faim.

Certains répertoires contiennent des fichiers ou d'autres répertoires (sous-répertoires). Et encore une fois, ce sous-répertoire peut contenir d'autres fichiers et sous-répertoires. Le répertoire crée une telle structure "imbriquée", une structure récursive. ... (snip) Le modèle composite sert à créer une telle structure, ** assimilant le conteneur au contenu et créant une structure récursive **

■ Exemple de programme "Composite"

En fait, je voudrais exécuter un exemple de programme qui utilise le modèle composite et vérifier le comportement suivant.

$ python Main.py 
Making root entries...
/root (30000)
/root/bin (30000)
/root/bin/vi (10000)
/root/bin/latex (20000)
/root/tmp (0)
/root/usr (0)

Making user entries...
/root (31500)
/root/bin (30000)
/root/bin/vi (10000)
/root/bin/latex (20000)
/root/tmp (0)
/root/usr (1500)
/root/usr/yuki (300)
/root/usr/yuki/diary.html (100)
/root/usr/yuki/Composite.java (200)
/root/usr/hanako (300)
/root/usr/hanako/memo.tex (300)
/root/usr/tomura (900)
/root/usr/tomura/game.doc (400)
/root/usr/tomura/junk.mail (500)

Occurring Exception...
FileTreatmentException

■ 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/Composite

.
├── Main.py
└── entry.py

(1) Le rôle de Leaf

C'est un rôle qui représente le «contenu». Rien d'autre ne peut être dans ce rôle. Dans l'exemple de programme, la classe File remplit ce rôle.

entry.py


class File(Entry):
    def __init__(self, name, size):
        self.name = name
        self.size = size

    def getName(self):
        return self.name

    def getSize(self):
        return self.size

    def _printList(self, prefix=''):
        print("{0}/{1}".format(prefix, self))

(2) Le rôle du composite

C'est un rôle qui représente un «conteneur». Vous pouvez entrer le rôle de «Feuille» ou le rôle de «Composite». Dans l'exemple de programme, la classe Directory remplit ce rôle.

entry.py


class Directory(Entry):
    def __init__(self, name):
        self.name = name
        self.directory = []

    def getName(self):
        return self.name

    def getSize(self):
        size = 0
        for d in self.directory:
            size += d.getSize()
        return size

    def add(self, entry):
        entry.path = self.name
        self.directory.append(entry)

    def _printList(self, prefix=''):
        print(prefix + "/" + str(self))
        for e in self.directory:
            e._printList(prefix + '/' + self.name)

(3) Rôle du composant

Il s'agit d'un rôle pour assimiler le rôle «Feuille» au rôle «Composite». Le rôle «Composant» est réalisé comme une superclasse commune au rôle «Feuille» et au rôle «Composite». Dans l'exemple de programme, la classe ʻEntry` remplit ce rôle.

entry.py


from abc import ABCMeta, abstractmethod

... (snip)

class Entry(metaclass=ABCMeta):
    @abstractmethod
    def getName(self):
        pass

    @abstractmethod
    def getSize(self):
        pass

    def add(self, entry):
        raise FileTreatmentException

    def printList(self):
        self._printList()

    @abstractmethod
    def _printList(self, prefix=''):
        pass

    def __str__(self):
        return "{0} ({1})".format(self.getName(), self.getSize())

(4) Le rôle du client

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

Main.py


from abc import ABCMeta, abstractmethod
from entry import Directory, File, FileTreatmentException


def startMain():
    try:
        print("Making root entries...")
        rootdir = Directory("root")
        bindir = Directory("bin")
        tmpdir = Directory("tmp")
        usrdir = Directory("usr")

        rootdir.add(bindir)
        rootdir.add(tmpdir)
        rootdir.add(usrdir)

        bindir.add(File("vi", 10000))
        bindir.add(File("latex", 20000))
        rootdir.printList()

        print("")
        print("Making user entries...")
        yuki = Directory("yuki")
        hanako = Directory("hanako")
        tomura = Directory("tomura")

        usrdir.add(yuki)
        usrdir.add(hanako)
        usrdir.add(tomura)

        yuki.add(File("diary.html", 100))
        yuki.add(File("Composite.java", 200))
        hanako.add(File("memo.tex", 300))
        tomura.add(File("game.doc", 400))
        tomura.add(File("junk.mail", 500))
        rootdir.printList()

        print("")
        print("Occurring Exception...")
        tmpfile = File("tmp.txt", 100)
        bindir = Directory("bin")
        tmpfile.add(bindir)
    except FileTreatmentException as ex:
        print(ex.message)

if __name__ == '__main__':
    startMain()

(5) Autre

Ajouter une classe d'exception

entry.py


class FileTreatmentException(Exception):
    def __init__(self,*args,**kwargs):
        self.message = "FileTreatmentException"

■ URL de référence

Recommended Posts

Apprenez le modèle de conception "Composite" 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 "É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
[Gang of Four] Apprentissage des modèles de conception - Composite
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
Lisez le fichier ligne par ligne avec Python