🐘 【Python】デザインパターン学習 - Strategyパターン -
作成日: 2021/10/31
0

Strategyパターンについて学ぶ

参考サイト1の動画で紹介されているTypeScriptのコードを自分なりにpythonに書き直して学習する。

Strategyパターンとは

ロジックを切り出して外部に書いて、ロジックの切り替えができるようにしたパターン

pythonでの書き方

from abc import ABCMeta, abstractmethod
import random
import json


class Sorter(metaclass=ABCMeta):
    """ソートのインターフェース"""
    @abstractmethod
    def sort(self, musics):
        pass


class RandumSorter(Sorter):
    """ランダムにソートするクラス"""
    def sort(self, musics):
        """ランダムにソートするメソッド
        
        :param musics: 音楽のデータが入っているリスト
        :type musics: list(dict())
        """
        return random.sample(musics,len(musics))


class ArtistSorter(Sorter):
    """作者の名前でソートするクラス"""

    def sort(self, musics):
        """作者の名前でソートするメソッド
        
        :param musics: 音楽のデータが入っているリスト
        :type musics: list(dict())
        """
        return sorted(musics, key = lambda x: x["artist"])


class Exporter(metaclass=ABCMeta):
    """出力するインターフェース"""

    @abstractmethod
    def export(self, musics):
        pass


class JsonExporter(Exporter):
    """Json形式で出力するクラス"""

    def export(self, musics):
        """Json形式で出力するメソッド
        
        :param musics: 音楽のデータが入っているリスト
        :type musics: list(dict())
        """
        return json.dumps(musics)


class CsvExporter(Exporter):
    """CSV形式で出力するクラス"""

    def export(self, musics):
        """CSV形式で出力するメソッド
        
        :param musics: 音楽のデータが入っているリスト
        :type musics: list(dict())
        """
        return "\n".join([music["title"] + "," + music["artist"] for music in musics])


class MusicList:
    """Musicリストをソートと出力形式を指定して出力するクラス"""

    def __init__(self, sorter, exporter):
        self.exporter = exporter
        self.sorter = sorter
    
    def export(self, musics):
        """Musicリストをソートと出力形式を指定して出力するメソッド
        
        :param musics: 音楽のデータが入っているリスト
        :type musics: list(dict())
        """
        SORTED = self.sorter.sort(musics)
        return self.exporter.export(SORTED)

DATA = [
    {"title": "ズルい女", "artist": "シャ乱Q"},
    {"title": "ロビンソン", "artist": "スピッツ"},
    {"title": "愛の言霊", "artist": "サザンオールスターズ"},
    {"title": "みんなのうた", "artist": "サザンオールスターズ"},
]

#SORTER = ArtistSorter()
SORTER = RandumSorter()
#EXPORTER = JsonExporter()
EXPORTER = CsvExporter()
MUSIC_LIST = MusicList(SORTER, EXPORTER)
print(MUSIC_LIST.export(DATA))

実行結果

ロビンソン,スピッツ
みんなのうた,サザンオールスターズ
ズルい女,シャ乱Q
愛の言霊,サザンオールスターズ

書いた感想

普通に書くとMusicListクラス内が肥大化するけど、別クラスで各ロジックを切り出すことでシンプルに書けた。ロジックを新たに追加することも容易でいいパターンだと思う。modeっていう変数を作って制御したいと思ったときに使えるかも。

書いたコード

github

参考サイト

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

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