I would like to learn GoF design patterns in Python.
The English word "Mediator" means "mediator". This pattern is a pattern that provides a simple and clear interface by making sure that the relationships between multiple objects that are intricately intertwined are processed through an "intermediary". In other words, the "Mediator" pattern plays the role of a "mediator" that receives inquiries from each of multiple objects under its jurisdiction, makes appropriate decisions, and gives instructions to all or part of the objects under its jurisdiction. It is a pattern that uses a class.
UML class and sequence diagram UML class diagram (The above is quoted from "Technical support site for IT engineers by IT Senka")
Actually, I would like to run a sample program that utilizes the Mediator pattern and check the following operation. Imagine a "user authentication screen" </ font> here.
--Suppose there is a user with username "hoge" and password "fuga" --** "login button" ** becomes active when username and password are entered -** Click "login button" ** to determine if user authentication was successful
In the sample program, by specifying the first argument: user name and the second argument: password, ", the user authentication screen" </ font> will be displayed with the user name. It is assumed that you have entered the password.
The username was entered correctly, so ** "login button" ** was enabled, but username authentication failed.
$ python Main.py hoge huga
(Active login button)
(ID/PW is incorrect)
Login Failed!!
** "login button" ** was not enabled and user authentication failed.
$ python Main.py hoge
Login Failed!!
Since the user name was entered correctly, ** "login button" ** was enabled and user authentication was successful.
$ python Main.py hoge fuga
(Active login button)
(ID/PW is confirmed)
Login Succeed!!
With the above, the sample program worked as expected.
Similar code has been uploaded to the Git repository. https://github.com/ttsubo/study_of_design_pattern/tree/master/Mediator
--Directory structure
.
├── Main.py
└── mediator
├── __init__.py
├── colleague.py
└── mediator.py
The Mediator
role communicates with the College
role and defines the interface for making adjustments.
In the sample program, the Mediator
class serves this role.
mediator/mediator.py
from abc import ABCMeta, abstractmethod
class Mediator(metaclass=ABCMeta):
@abstractmethod
def on_change(self, component):
pass
The ConcreteMediator
role implements the interface for the Mediator
role and makes the actual adjustments.
In the sample program, the ConcreteMediator
class serves this role.
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)")
The Colleague
role associates the Mediator
role with the interface that communicates.
In the sample program, the Colleague
class serves this role.
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)
The ConcreteColleague
role is associated with the Colleague
role.
In the sample program, the ConcreteColleagueButton
class and the ConcreteColleagueTextArea
class serve this role.
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()
In the sample program, the startMain
method serves this role.
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)
-Design pattern in Python ~ Py design pattern ~ / Mediator pattern
Recommended Posts