[PYTHON] Design Pattern #Facade

I practiced design patterns so that I could write code that was conscious of design. Other Design Patterns will be released frequently.

Preface

The primary goal is to understand when, what, and how to use design patterns. (I'm new to Java or a statically typed language, and I don't have a long history of python, so I think there are some things that aren't like Pythonista. If you have any suggestions, please teach me.)

This time, the structure-related pattern Facade pattern.

What is Facade

The Facade acts as a simple window to complex systems. In other words, simplify the large logic and combine it into one simple function call.

Overview

The sample program created here creates a user's web page. In order to make a sample of the Facade pattern, we originally need "a lot of complicated and intricate classes". However, in order to shorten the sample program, we will consider a simple system consisting of only three classes. This system consists of a database that gets a name from an email address, a class that creates an HTML file (HTMLWriter), and a class that provides a high-level interface as a Facade (PageMaker).

Overall class diagram

database.py


from configparser import ConfigParser
import logging


class Database():

    def get_properties(self, dbname):
        filename = dbname + '.ini'
        conf = ConfigParser()
        try:
            conf.read(filename)
            prob = conf['TEST1']
            return prob
        except IOError:
            logging.exception('Warning' + filename + 'is not found.')

The Database class gets the user_name by specifying the database name ("maildata").

maildata.ini


[TEST1]
[email protected]=Hiroshi Yuki
[email protected]=Hananko Sato

The data file you are referencing.

html_writer.py


class HtmlWriter():

    def __init__(self, writer):
        self.__writer = writer

    def title(self, title):
        self.__writer.write('<!DOCTYPE html> \n')
        self.__writer.write('<html>')
        self.__writer.write('<head>')
        self.__writer.write('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> \n')
        self.__writer.write('<title>' + title + '</title>')
        self.__writer.write('</head>')
        self.__writer.write('<body> \n')
        self.__writer.write('<h1>' + title + '<h1> \n')

    def paragraph(self, msg):
        self.__writer.write('<p>' + msg + '</p>\n')

    def link(self, href, caption):
        self.paragraph('<a href=\'' + href + '\' >' + caption + '</a>')

    def mailto(self, mailaddr, username):
        self.link('mailto:' + mailaddr, username)

    def close(self):
        self.__writer.write('</body>')
        self.__writer.write('</html>\n')
        self.__writer.close()

The HtmlWriter class creates simple web pages. Give a writer when creating an instance, and output HTML to that writer.

The title method outputs the title, the paragraph method outputs the paragraph, the link method outputs the link, the mailto method outputs the link of the email address, and the close method ends the HTML output.

This class hides the constraint that the title method must be called first. And the PageMaker class, which serves as a window, is written to comply with that constraint.

page_maker.py


import logging
from html_writer import HtmlWriter
from database import Database


class PageMaker():

    def make_welcome_page(self, mailaddr, filename):
        db = Database()
        try:
            prob = db.get_properties('maildata')
            user_name = prob[mailaddr]
            writer = HtmlWriter(open(filename, mode='w'))
            writer.title('Welcome to ' + user_name + 'is page!')
            writer.paragraph(user_name + 'Welcome to the page.')
            writer.paragraph('I'm waiting for an email.')
            writer.mailto(mailaddr, user_name)
            writer.close()
            print(filename + ' ' + 'is created for' + mailaddr + ' ' + '(' + user_name + ')')
        except IOError as e:
            logging.exception(e)

The PageMaker class is a combination of the Database class and the HtmlWriter class to create a web page for a specified user.

The only public method defined in this class is make_welcome_page. Specifying an email address and output file name for this method will create a web page.

Where the methods of the HtmlWriter class are messed up, this PageMaker class takes care of it, ** showing only one make_welcome_page method to the outside **. This is a simple window.

main.py


from page_maker import PageMaker


def main():
    pm = PageMaker()
    pm.make_welcome_page('[email protected]', 'welcome.html')

if __name__ == '__main__':
    main()

Execution result welcome.html is created [email protected] (Hiroshi Yuki)

welcom.png

Summary

Facade makes sure that if you want to work with a class, you don't have to worry about the complexity of calling the methods of that class or if the initialization method is complicated. The point is to reduce the number of interfaces and combine them into one simple function call.

As a result, the connection with the outside becomes loose and it becomes easy to reuse. In other words, it makes it easy to hide object-oriented information.

reference

Recommended Posts

Design Pattern #Facade
Design Pattern #Builder
Design Pattern #Adapter
Design Pattern #Decorator
Design Pattern #Observer
Design Pattern #Strategy
Design Pattern #Singleton
Design Pattern #Proxy
[Gang of Four] Design pattern learning --Facade
Learn the design pattern "Facade" with Python
Facade pattern in Java
Design Pattern #Factory Method
Design Pattern #Template Method
Ore Ore Design Pattern: Glocal Variable
Python Design Pattern --Template method
[Gang of Four] Design pattern learning
GoF java design pattern rough summary
Design patterns to enjoy with frequently used Java libraries --Facade pattern
Learn the design pattern "Prototype" in Python
Learn the design pattern "Builder" in Python
[Gang of Four] Design pattern learning --Singleton
[Gang of Four] Design Pattern Learning --Decorator
[Gang of Four] Design pattern learning --Visitor
Design pattern-Adapter
[Gang of Four] Design pattern learning --Mediator
Learn the design pattern "Observer" in Python
Learn the design pattern "Proxy" in Python
Learn the design pattern "Command" in Python
[Gang of Four] Design pattern learning --Iterator
GoF design pattern from the problem 2. Structure
Learn the design pattern "Visitor" in Python
Learn the design pattern "Bridge" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
[Gang of Four] Design pattern learning --Composite
[Gang of Four] Design pattern learning --Prototype
GoF design pattern from the problem 1. Generation
Learn the design pattern "Iterator" in Python
[Gang of Four] Design pattern learning --Memento
[Gang of Four] Design pattern learning --State
[Gang of Four] Design pattern learning --Interpreter
[Gang of Four] Design pattern learning --Builder
Learn the design pattern "Strategy" in Python
[Gang of Four] Design pattern learning --Bridge
Learn the design pattern "Composite" in Python
Learn the design pattern "Singleton" with Python
Learn the design pattern "State" in Python
Learn the design pattern "Adapter" in Python
[Gang of Four] Design pattern learning --Proxy
[Gang of Four] Design pattern learning --Strategy
[Gang of Four] Design pattern learning --Adapter
[Gang of Four] Design pattern learning --Observer
[Gang of Four] Design pattern learning --Command
GoF design pattern from the problem 3. Behavior
[Gang of Four] Design pattern learning --Fly Weight
[Gang of Four] Design pattern learning --Abstract Factory
Learn the design pattern "Abstract Factory" in Python
Learn the design pattern "Template Method" in Python
[Gang of Four] Design pattern learning --Factory Method
Learn the design pattern "Factory Method" in Python
I wrote a design pattern in kotlin Prototype