abstract_factoryパターンは、共通性のある部品をあらかじめ作成しておき再利用します。
from abc import ABC, abstractmethod
# 各製品の部品を生成するための、継承先となる抽象クラス(Product)
class AbcItem(ABC):
def __init__(self, caption):
self.caption = caption
@abstractmethod
def make_html(self):
pass
class PageItem(AbcItem):
def __init__(self, title, author):
self.title = title
self.author = author
self.content = []
def add(self, item):
self.content.append(item)
def write_html(self, file_name):
with open(file_name, 'w', encoding='utf-8') as fh:
fh.write(self.make_html())
class LinkItem(AbcItem):
""""""
def __init__(self, caption, url):
super().__init__(caption)
self.url = url
class ListItem(AbcItem):
""" """
def __init__(self, caption):
super().__init__(caption)
self.items = []
def add(self, item):
self.items.append(item)
# Productを生成する Factory の定義
class Factory(ABC):
@abstractmethod
def create_page_item(self, title, author):
pass
@abstractmethod
def create_link_item(self, caption, url):
pass
@abstractmethod
def create_list_item(self, caption):
pass
# concrete_factory.py
from abstract_factory import(
LinkItem, ListItem, PageItem, Factory
)
class HtmlPateItem(PageItem):
def __init__(self, title, author):
super().__init__(title, author)
#abstractmethodの具体化
def make_html(self):
output = f'<html>\n<head>\n<title>{self.title}' \
f'</title>\n</head>\n'
output += f'<body>\n'
output += f'<h1>{self.title}</h1>\n'
output += f'<ul>'
for list_item in self.content:
output += list_item.make_html()
output += f'</ul>\n'
output += f'<hr>\n<address>{self.author}</address>\n'
output += '</body></html>'
return output
class HtmlLinkItem(LinkItem):
def __init__(self, caption, url):
super().__init__(caption, url)
def make_html(self):
return f'<li><a href="{self.url}">{self.caption}</a></li>'
class HtmlListItem(ListItem):
""" link item を入れる """
def __init__(self, caption):
super().__init__(caption)
def make_html(self):
output = '<li>\n'
output += self.caption + '\n'
output += '<ul>\n'
for link_item in self.items:
output += link_item.make_html()
output += '</ul>\n'
output += '</li>\n'
return output
# ConcreteProductを生成する ConcreteFactory
class HtmlFactory(Factory):
def create_page_item(self, title, author):
return HtmlPateItem(title, author)
def create_link_item(self, caption, url):
return HtmlLinkItem(caption, url)
def create_list_item(self, caption):
return HtmlListItem(caption)
if __name__ == '__main__':
html_factory = HtmlFactory()
asahi = html_factory.create_link_item('Asahi News Paper', 'http://asahi')
yomiuri = html_factory.create_link_item('Yomiuri news paper', 'http://yomiuri')
yahoo = html_factory.create_link_item('Yahoo', 'http://yahoo')
google = html_factory.create_link_item('Google', 'http://google')
wikipedia = html_factory.create_link_item('Wikipedia', 'http://wikipedia')
news_pages = html_factory.create_list_item('News Paper')
news_pages.add(asahi)
news_pages.add(yomiuri)
other_pages = html_factory.create_list_item('Other pages')
other_pages.add(yahoo)
other_pages.add(google)
other_pages.add(wikipedia)
all_page = html_factory.create_page_item('My Page', 'Taro')
all_page.add(news_pages)
all_page.add(other_pages)
all_page.write_html('tmp.html')