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

J'aimerais apprendre les modèles de conception GoF en Python.

■ Médiateur (modèle de médiateur)

Le mot anglais «Mediator» signifie «médiateur». Ce modèle est un modèle qui fournit une interface simple et claire en s'assurant que les relations entre plusieurs objets intimement entrelacés sont traitées par un «intermédiaire». En d'autres termes, le modèle "Mediator" agit comme un "médiateur" qui reçoit les demandes de chacun d'une pluralité d'objets relevant de sa compétence, prend les décisions appropriées et donne des instructions à tout ou partie des objets relevant de sa compétence. C'est un modèle qui utilise une classe.

UML class and sequence diagram W3sDesign_Mediator_Design_Pattern_UML.jpg UML class diagram designpattern-mediator01.gif (Ce qui précède est tiré du "Site de support technique pour les ingénieurs informatiques par IT Senka")

■ Exemple de programme "Mediator"

En fait, je voudrais essayer d'exécuter un exemple de programme qui utilise le modèle Mediator et vérifier le comportement suivant. Imaginez un "écran d'authentification utilisateur" </ font> ici.

  • Supposons qu'il y ait un utilisateur avec le nom d'utilisateur "hoge" et le mot de passe "fuga"
  • ** "bouton de connexion" ** devient actif lorsque le nom d'utilisateur et le mot de passe sont saisis
  • ** Cliquez sur "bouton de connexion" ** pour déterminer si l'authentification de l'utilisateur a réussi

Dans l'exemple de programme, en spécifiant le premier argument: nom d'utilisateur et le deuxième argument: mot de passe, "vilain, écran d'authentification de l'utilisateur" </ font> sera affiché avec le nom d'utilisateur. Il est supposé que vous avez saisi le mot de passe.

(Cas 1) L'authentification de l'utilisateur échoue en spécifiant un mot de passe incorrect

Le nom d'utilisateur a été entré correctement, donc le ** "bouton de connexion" ** a été activé, mais l'authentification de l'utilisateur a échoué.

$ python Main.py hoge huga
(Active login button)
(ID/PW is incorrect)
Login Failed!!

(Cas 2) L'authentification de l'utilisateur échoue car le mot de passe n'a pas été spécifié.

L'authentification de l'utilisateur a échoué car le ** "bouton de connexion" ** n'a pas été activé.

$ python Main.py hoge
Login Failed!!

(Cas 3) L'authentification de l'utilisateur réussit en spécifiant le nom d'utilisateur et le mot de passe corrects.

Étant donné que le nom d'utilisateur a été saisi correctement, ** "bouton de connexion" ** a été activé et l'authentification de l'utilisateur a réussi.

$ python Main.py hoge fuga
(Active login button)
(ID/PW is confirmed)
Login Succeed!!

L'exemple de programme a fonctionné comme prévu.

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

  • Structure du répertoire
.
├── Main.py
└── mediator
    ├── __init__.py
    ├── colleague.py
    └── mediator.py

(1) Le rôle du médiateur (médiateur, médiateur)

Le rôle «Médiateur» communique avec le rôle «Collègue» et définit l'interface pour effectuer les ajustements. Dans l'exemple de programme, la classe Mediator remplit ce rôle.

mediator/mediator.py


from abc import ABCMeta, abstractmethod

class Mediator(metaclass=ABCMeta):
    @abstractmethod
    def on_change(self, component):
        pass

(2) Le rôle de ConcreteMediator (médiateur concret, médiateur)

Le rôle ConcreteMediator implémente l'interface pour le rôle Mediator et effectue les ajustements réels. Dans l'exemple de programme, la classe ConcreteMediator remplit ce rôle.

mediator/mediator.py


class ConcreteMediator(Mediator):
    def __init__(self):
        self.authentication = False

    def setColleagues(self, inputIdObj, inputPwObj, buttonObj):
        self.inputIdObj = inputIdObj
        self.inputPwObj = inputPwObj
        self.buttonObj = buttonObj

    def on_change(self, component):
        if component.name == "ID" or component.name == "PW":
            self.__refreshButton()
        elif component.name == "Login":
            self.__authentication()

    def __refreshButton(self):
        if self.inputIdObj.text is not None and self.inputPwObj.text is not None:
            print("(Active login button)")
            self.buttonObj.active = True

    def __authentication(self):
        if self.inputIdObj.text == "hoge" and self.inputPwObj.text == "fuga":
            print("(ID/PW is confirmed)")
            self.authentication = True
        else:
            print("(ID/PW is incorrect)")

(3) Le rôle du collègue

Le rôle «Collègue» associe le rôle «Médiateur» à l'interface qui communique. Dans l'exemple de programme, la classe Colleague remplit ce rôle.

mediator/colleague.py


from mediator.mediator import Mediator

class Colleague(Mediator):
    def __init__(self, mediatorObj, name):
        self.mediator = mediatorObj
        self.name = name

    def on_change(self):
        if self.mediator is not None:
            self.mediator.on_change(self)

(4) Le rôle de Concrete College

Le rôle ConcreteColleague est associé au rôle Colleague. Dans l'exemple de programme, la classe ConcreteColleagueButton et la classe ConcreteColleagueTextArea remplissent ce rôle.

mediator/colleague.py


class ConcreteColleagueButton(Colleague):
    def __init__(self, mediatorObj, name=None):
        super(ConcreteColleagueButton, self).__init__(mediatorObj, name)
        self.active = False

    def clickButton(self):
        if self.active:
            self.on_change()
        return self.mediator.authentication

    def checkButtonStatus(self):
        return self.active

class ConcreteColleagueTextArea(Colleague):
    def __init__(self, mediatorObj, name=None):
        super(ConcreteColleagueTextArea, self).__init__(mediatorObj, name)
        self.text = None

    def inputText(self, text):
        self.text = text
        self.on_change()

(5) Le rôle du client

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

Main.py


import sys
from mediator.mediator import ConcreteMediator 
from mediator.colleague import ConcreteColleagueTextArea, ConcreteColleagueButton


def startMain(userid, password):
    m = ConcreteMediator()
    inputIdObj = ConcreteColleagueTextArea(m, "ID")
    inputPwObj = ConcreteColleagueTextArea(m, "PW")
    pushButtonObj = ConcreteColleagueButton(m, "Login")
    m.setColleagues(inputIdObj, inputPwObj, pushButtonObj)

    inputIdObj.inputText(userid)
    inputPwObj.inputText(password)
    if pushButtonObj.clickButton():
        print("Login Succeed!!")
    else:
        print("Login Failed!!")

def check_input_data(params):
    if len(params)==3:
        userid = params[1]
        password = params[2]
    elif len(params)==2:
        userid = params[1] 
        password = None
    elif len(params)==1:
        userid = None
        password = None
    return userid, password

if __name__ == "__main__":
    userid, password = check_input_data(sys.argv)
    startMain(userid, password)

■ URL de référence

Recommended Posts