‍🦔 【Python】デザインパターン学習 - Singletonパターン -
作成日: 2021/11/15
0

Singletonパターンについて学ぶ

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

Singletonパターンとは

生成されるインスタンスを一つに限定する方法。一つのインスタンスを使いまわしたいときに便利。

pythonでの書き方

class UserCart:
    _instance = None
    items = []

    def __new__(cls):
        raise NotImplementedError('Cannot initialize via Constructor')

    @classmethod
    def __internal_new__(cls):
        return super().__new__(cls)

    @classmethod
    def get_instance(cls):
        if not cls._instance:
            cls._instance = cls.__internal_new__()

        return cls._instance

    def add(self, item):
        print("{}がカートに追加されました".format(item))
        self.items.append(item)

    def reset(self):
        self.items = []
    
    def is_added(self, item_name: str):
        return any([('name',item_name) in item.items() for item in self.items])

    def print_items(self):
        print('カート -----------')

        if len(self.items) == 0:
            print('カートに商品がありません')
            return
        
        for item in self.items:
            print("商品名:{0},価格:{1}".format(item['name'], item['price']))
        
    def calc(self):
        return sum([item['price'] for item in self.items])

class ItemList:

    def __init__(self):
        self.init_data()

    def init_data(self):
        self.data = [
            {'name': 'hoge', 'price': 3000},
            {'name': 'fuge', 'price': 5000},
            {'name': 'hoga', 'price': 2500},
        ]
    
    def find_by(self, name: str):
        for item in self.data:
            if ('name', name) in item.items():
                return item

    def get_data(self):
        return self.data

class Purchase:

    def __init__(self):
        self.cart = UserCart.get_instance()
    
    def payment(self):
        print('商品を購入しました')
        self.cart.reset()

    def print_total_price(self):
        total_price = self.cart.calc() * 1.1
        print('購入商品の合計額は{}円です'.format(total_price))

def display_itemlist(item_list):
    print('商品リスト -----------')
    for item in item_list:
        print_str = '商品名:' + item['name'] + ', 価格:' + str(item['price'])
        if UserCart.get_instance().is_added(item['name']):
            print_str += '(カート追加済み)'
        print(print_str)

PURCHASE = Purchase()
ITEM_LIST = ItemList()
USER_CART = UserCart.get_instance()

display_itemlist(ITEM_LIST.get_data())
USER_CART.print_items()
USER_CART.add(ITEM_LIST.find_by('hoge'))
USER_CART.print_items()
USER_CART.add(ITEM_LIST.find_by('fuge'))
USER_CART.print_items()
display_itemlist(ITEM_LIST.get_data())
PURCHASE.print_total_price()
PURCHASE.payment()
USER_CART.print_items()

実行結果

商品リスト -----------
商品名:hoge, 価格:3000
商品名:fuge, 価格:5000
商品名:hoga, 価格:2500
カート -----------
カートに商品がありません
{'name': 'hoge', 'price': 3000}がカートに追加されました
カート -----------
商品名:hoge,価格:3000
{'name': 'fuge', 'price': 5000}がカートに追加されました
カート -----------
商品名:hoge,価格:3000
商品名:fuge,価格:5000
商品リスト -----------
商品名:hoge, 価格:3000(カート追加済み)
商品名:fuge, 価格:5000(カート追加済み)
商品名:hoga, 価格:2500
購入商品の合計額は8800.0円です
商品を購入しました
カート -----------
カートに商品がありません

書いた感想

Pythonでの書き方は参考サイト2を参照した。どこから呼び出しても同じインスタンスを利用できるのが保証されるというのはシーンによっては便利だと思った。

書いたコード

github

参考サイト

  1. Singletonパターン【コードで理解する】- プログラミング相談所オンライン
  2. Pythonでシングルトン(Singleton)を実装してみる

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