I practiced design patterns so that I could write code that was conscious of design. Other Design Patterns will be released frequently.
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.
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.
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).
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)
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.
Recommended Posts