🐣 【Python】デザインパターン学習 - Compositeパターン -
作成日: 2021/10/24
0

Compositeパターンについて学ぶ

参考サイト1の動画で紹介されているTypeScriptのコードを自分なりにpythonに書き直して学習する。Compositパターンについての詳しい解説は参考サイト1,もしくは2を参照のこと。

Compositeパターンとは

木構造を表し、親と子に同一の操作を実施させたい場合に便利なパターン。

pythonでの書き方

from abc import ABCMeta, abstractmethod

class Component(metaclass=ABCMeta):
    @abstractmethod
    def print(self,num:int)->None:
        pass
    
    @abstractmethod
    def add(self,component)->None:
        pass

class AbstractComponent(Component):
    
    def getName(self):
        return self.name
    
    def createIndent(self,num:int):
        return " " * num

    def add(self,component:Component):
        raise Exception("add is not defined")
    
    def print(self,num:int)->None:
        pass

class Category(AbstractComponent):

    def __init__(self,name:str) -> None:
        self.name = name
        self.components = []
    
    def print(self,index:int = 0):
        INDENT = self.createIndent(index)
        print(INDENT + "#" + self.getName())
        index += 1
        for component in self.components:
            component.print(index)
    
    def add(self, component: Component):
        self.components.append(component)

class Shop(AbstractComponent):
    
    def __init__(self,name) -> None:
        self.name = name
    
    def print(self,index:int = 0):
        INDENT = self.createIndent(index)
        print(INDENT + "##" + self.getName())

ROOT_CATEGORY = Category('フレンチ')
CHILD_CATEGORY_1 = Category('レストラン')
CHILD_CATEGORY_2 = Category('ビストロ')
SHOP1 = Shop('ショップ1')
SHOP2 = Shop('ショップ2')
SHOP3 = Shop('ショップ3')
SHOP4 = Shop('ショップ4')
SHOP5 = Shop('ショップ5')
SHOP6 = Shop('ショップ6')

ROOT_CATEGORY.add(SHOP1)
ROOT_CATEGORY.add(SHOP2)
ROOT_CATEGORY.add(SHOP3)
ROOT_CATEGORY.add(CHILD_CATEGORY_1)
CHILD_CATEGORY_1.add(SHOP4)
CHILD_CATEGORY_1.add(SHOP5)
ROOT_CATEGORY.add(CHILD_CATEGORY_2)
CHILD_CATEGORY_2.add(SHOP6)

ROOT_CATEGORY.print()
print('======')
SHOP1.print()
print('======')
CHILD_CATEGORY_1.print()

実行結果

#フレンチ
 ##ショップ1
 ##ショップ2
 ##ショップ3
 #レストラン
  ##ショップ4
  ##ショップ5
 #ビストロ
  ##ショップ6
======
##ショップ1
======
#レストラン
 ##ショップ4
 ##ショップ5

書いた感想

同じ抽象クラスを継承することでツリー構造の親クラスと子クラスに同じメソッドを実装させて同じメソッドが実装されているからこそ繰り返し処理ができるという構造が上手いと感じた。なおかつ、これはツリー構造の親クラスと子クラスという関係であるが、実装上は親子関係にない。つまり、親子関係を実装する訳にはいかないが、親子にしたい場合に有効な方法だと思った。

書いたコード

github

参考サイト

  1. Compositeパターン【コードで理解する】- プログラミング相談所オンライン
  2. Tech lib Compositeパターン

フリーランスでpythonエンジニアとして働きたく勉強中。 前職は運用SEとセキュリティエンジニア。 開発は学校で学んだ経験と趣味でやっていた程度。一応前職でも業務の自動化のためにExcel VBAやセキュリティテスト用のWebサイトの開発やセキュリティテストツールの改良などで開発はやっていた。