Facadeパターン

本記事はGoFのデザインパターンの1つであるFacadeパターンについての解説と実際に実装した記事になります。 ソースコード

適応可能性

  • 複数のサブシステムを統合したインタフェースが必要な場合
  • 複数の依存したサブシステム同士を単純な依存関係で繋げたい場合

解決策

複数のサブシステムを適切に呼び出してあげることで、クライアントからの要求を単純にできるようなインタフェースを作ること。
また、これによって要求の内部実装を隠蔽することができます。
(ただし、完璧に隠蔽する必要はなくクライアントが直接サブシステム内のクラスを参照することは可能)

コード例

クライアントの用件が複数ある場合は、Facadeの抽象クラスを作ることで解決することができます。

まずは簡単なhtmlを作成するクラスとテキストファイルを出力する関数を定義します。


def write_text_file(text, file_path):
    with open(file_path, 'wt') as f:
        f.write(text)


class HtmlWriter:

    def __init__(self):
        self._html = '''
        <html>
        <head>{}</head>
        <body>{}</body>
        </html>
        '''

        self._head = '<title>home</title>'
        self._body = ''

    @property
    def html(self):
        return self._html.format(self._head, self._body)

    @property
    def body(self):
        return self._body

    @body.setter
    def body(self, body):
        self._body = body

これらを片方または両方を統合したインタフェースを提供するfacadeクラスを作成します。


class FacadePrintConsole(Facade):

    def output(self, my_name):
        html_writer = HtmlWriter()
        html_writer.body = f'<h1>Welcome to {my_name} page</h1>'
        print(html_writer.html)


class FacadeMakeHtml(Facade):

    def output(self, my_name):
        html_writer = HtmlWriter()
        html_writer.body = f'<h1>Welcome to {my_name} page</h1>'
        write_text_file(html_writer.html, 'index.html')

mainではfacadeを通して処理を要求します。


if __name__ == '__main__':
    facade = FacadePrintConsole()
    facade.output(my_name='tanaka taro')

    facade = FacadeMakeHtml()
    facade.output(my_name='tanaka jiro')