[PYTHON] I studied about design patterns (personal memo) Part 6 (Chain of Responsibility pattern, Facade pattern, Mediator pattern)


This article is a personal study memo. I am writing an article driven by the obsession that what I input must be output. I am writing this article on Qiita with the hope that someone who is familiar with it will be able to point out mistakes and give advice.

I live a working life as an engineer, but I haven't learned about design patterns properly, so I studied.

What is described here https://github.com/ck-fm0211/notes_desigh_pattern I'm uploading to.

Past log

I studied about design patterns (personal memo) Part 1 I studied about design patterns (personal memo) Part 2 I studied about design patterns (personal memo) Part 3 I studied about design patterns (personal memo) Part 4 I studied about design patterns (personal memo) Part 5

Chain of Responsibility pattern

――The Chain of Respoisibility pattern is a pattern that makes you imagine a state in which those who have "responsibility" are connected in a "chain" shape. --Example: --If you ask the "section chief" to settle something, the section chief will approve it if it can be dealt with by the section chief's approval. --For items that cannot be handled by the section chief, the "manager" will be asked to make a decision. ――Of course, if the content cannot be approved by the director, the approval will be entrusted to a higher-level decision-maker. --A pattern that connects the "responsible person" in a "chain" and expresses that "someone" will process at "some stage".

Actually use


――Think about the decision at school --Student A "How much is the snack for the excursion?" --Rookie teacher "up to 300 yen" ← Approval of new teacher --Student B "Does bananas fit in a snack?" --Rookie teacher "I can't judge" --Veteran teacher "I can't enter the snack" ← Veteran teacher's decision --Student's parents "Can I have a mobile phone?" --Rookie teacher / Veteran teacher "I can't judge" --Decision at the staff meeting ← Higher-level approval

――The chain that "the responsible person decides what he / she can judge at his / her own discretion, and leaves the judgment to the next person in charge if he / she cannot judge by himself / herself"

--To use the Chain of Responsibility pattern, create a "class that represents general responsibility" and inherit it to create classes such as students, new teachers, veteran teachers, and staff meetings. --The "class that represents the general responsible person" has a method to "judgment" and a field variable that represents the "next responsible person" to ask for judgment if it cannot be judged by oneself. --The class representing each responsible person is created by inheriting this "class representing general responsible person".

# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod

class Responsible(metaclass=ABCMeta):

    def __init__(self, responsible_person: str):
        self._responsible_person = responsible_person
        self._next_level: Responsible = None

    def set_next(self, next_level):
        self._next_level = next_level
        return self._next_level

    def be_able_to_judge(self, question: Question) -> bool:

    def judge(question: Question):

    def put_question(self, question: Question):
        if self.be_able_to_judge(question):
        elif self._next_level is not None:
            print("No one could judge. Try it.")

class Question:
A String instance that stores the content of the question as a field, and
It has a Level instance that represents the difficulty of the question.

    def __init__(self, question: str, level: Level):
        self._question = question
        self._level = level

class Level:
An int type value that represents the difficulty level as a field,
LessThan comparing its own difficulty with the difficulty of the argument Level object(Level level)Have a method

    def __init__(self, level: int):
        self._level: int = level

    def less_than(self, level: Level):

class RookieTeachee(Responsible):

    def __init__(self, responsible_person):
        self._level = Level(2)

    def be_able_to_judge(self, question: Question):
        if question._level.less_than(self._level):
            return True

        return False

    def judge(question: Question):
        #・ ・ ・

--By dividing each "responsible person" into classes, the role of each person in charge can be limited. ――By clarifying the role of the person in charge and dividing the person in charge into classes, it becomes possible to more flexibly rearrange the “chain” that is the flow of judgment. ――On the other hand, it is possible that the processing speed will slow down because the chain is followed each time. ――It is necessary to judge depending on the situation whether a speed-oriented program is required or flexibility is required.

Summary of Chain of Responsibility patterns


Facade pattern

――The Facade pattern is a pattern that makes it possible to simply use the procedure of using multiple existing classes in combination by creating a class that serves as a "window".

Actually use


――I went to the library to borrow a book, but I don't know where it is. ――I have a list of books and a loan book, but I don't know how to use them.

# -*- coding:utf-8 -*-

class BookList:
    """Collection list"""

    def search_book(book_name):
        location = None
        #Search by book name
        #Returns the location, if any, null otherwise
        return location

class LendingList:
    """Lending book"""

    def check(book_name):
        #Check the loan book
        #Returns true if rented, false otherwise
        return True

class Visitor:
    def main(args):
        #Where is the book you want to borrow?
        #When and where do you use which method?

--Ask the librarian ――This is the "window"

class Visitor:
    def main(args):
        #Ask the librarian at the counter for the location
        shisho = Librarian()
        location = shisho.search_book("Insect picture book")
        if location == "Lending":
            print("Is it on loan! !!")
        elif location == "The book is not in the possession":
            print("Isn't it! !! !!")
            print("Thank you")

class Librarian:
    def search_book(book_name):
        #Find a book
        location = BookList.search_book(book_name)
        #When the location of the book is not None (in possession)
        if location is not None:
            #Check if it is on loan
            if LendingList.check(book_name):
                #When renting
                return "Lending"
                #When not on loan
                return location
            #When not in possession
            return "The book is not in the possession"

Summary of Facade patterns


Mediator pattern

--A pattern that is effective when used when it is necessary to proceed with processing while making adjustments between a large number of objects. --Example --A policeman who maintains traffic at an intersection where the signal is broken --Judge the situation and instruct "stop" and "advance" --A pattern that uses a class that acts as an "arbitrator" who receives inquiries from each object, makes appropriate decisions, and gives instructions in order to make adjustments between multiple objects.

Actually use


--Matching app --Respond to the request by looking at the situation

# -*- coding:utf-8 -*-

class Concierge:

    def __init__(self):
        self._user_dict = {}

    def add_user(self, user: User):
        self._user_dict[user.get_name()] = user

    def consultation(colleagueInLove: User, secretLover: User):
        possibility = 0
        #Derivation of possibility in consideration of various situations
        return possibility

class User:
    def __init__(self):
        self._name = None

    def get_name(self):
        return self._name

class John(User):

    def __init__(self):
        self._name = "John"
        self._secret_lover = None
        self._tension = None
        self._mediator = Concierge()

    def get_name(self):
        return self._name

    def set_secret_lover(self, user: User):
        self._secret_lover = user

    def needs_advice(self):
        self._tension = self._mediator.consultation(self, self._secret_lover)

--The Mediator pattern can be used for input interfaces, etc. --Example When you want to create a "button that does not become" valid "unless it meets certain intricately intertwined conditions" --"When radio button A is selected and there is input in the text box" or "When radio button B is selected and check box C or D is checked", " Buttons that become "enabled" verify "whether there is input in the text box" when "radio button A" is checked, or "checkbox C or D is checked" when radio button B is selected. If you have a program that verifies "whether it is done", it will be a program that needs to be verified even when check box C is checked or check box D is unchecked. ――As the conditions become more complex, you will lose control of where and what you are checking. --In the Mediator pattern, each object contacts Mediator when its state changes, and Mediator comprehensively determines the state of each object, not just the object whose state has changed, and presses a "button". It is designed to convey "valid" and "invalid" to the indicated object, which makes management relatively easy.

Summary of Mediator patterns


Recommended Posts

I studied about design patterns (personal memo) Part 6 (Chain of Responsibility pattern, Facade pattern, Mediator pattern)
I studied about design patterns (personal memo) Part 3 (Prototype pattern, Builder pattern)
I studied about design patterns (personal memo) Part 5 (Composite pattern, Decorator pattern, Visitor pattern)
I studied about design patterns (personal memo) Part 4 (AbstractFactory pattern, Bridge pattern, Strategy pattern)
I studied about design patterns (personal memo) Part 8 (Proxy pattern, Command pattern, Interpreter pattern)
I studied about design patterns (personal memo) Part 7 (Observer pattern, Memento pattern, State pattern, Flyweight pattern)
[Gang of Four] Design pattern learning --Chain of Responsibility
Learn the design pattern "Chain of Responsibility" in Python
Chain of Responsibility pattern in Java
[Gang of Four] Design pattern learning --Mediator
[Gang of Four] Design pattern learning --Facade
Design Pattern #Facade