Python デザインパターン サンプルコード Memento
結城 浩「Java言語で学ぶデザインパターン入門」をPython化
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-19)Python3.11で動作確認済み
Memento Gamer (getMoney, addFruit, getFruits) (getMoney, bet, createMemento, restoreMemento, getFruit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import copy import random import time class Memento(object): def __init__(self, money): # コンストラクタ(wide interface) self.money = money # 所持金 self.fruits = [] # フルーツ def getMoney(self): # 所持金の値を得る(narrow interface) return self.money def addFruit(self, fruit): # フルーツを追加する(wide interface) self.fruits.append(fruit) def getFruits(self): # フルーツを得る(wide interface) return copy.deepcopy(self.fruits) class Gamer(object): fruitsname = ["リンゴ", "ぶどう", "バナナ", "みかん"] # フルーツ名の表 def __init__(self, money): # コンストラクタ self.money = money # 所持金 self.fruits = [] # フルーツ # random.seed(314) def getMoney(self): # 現在の所持金の値を得る return self.money def bet(self): # 賭ける…ゲームの進行 dice = random.randint(1, 6) # サイコロを振る if dice == 1: # 1の目…所持金が増える self.money += 100 print("所持金が増えました") elif dice == 2: self.money /= 2 # 2の目…所持金が半分になる print("所持金が半分になりました") elif dice == 6: # 6の目…フルーツをもらう f = self.getFruit() print("フルーツ({})をもらいました".format(f)) self.fruits.append(f) else: # それ以外…何も起きない print("何も起こりませんでした。") def createMemento(self): # スナップショットをとる m = Memento(self.money) it = iter(self.fruits) for f in it: if f.startswith("おいしい"): # 文字列の先頭を調べる m.addFruit(f) # フルーツはおいしいものだけ保存 return m def restoreMemento(self, memento): # アンドゥを行う self.money = memento.getMoney() self.fruits = memento.getFruits() # print(memento.__dict__) # debug def __str__(self): # インスタンスがprintされると呼ばれる return "[money = {}, fruits = {}]".format(self.money, self.fruits) def getFruit(self): # フルーツを1個得る prefix = "" if bool(random.getrandbits(1)): # 1bitの乱数 prefix = "おいしい" return prefix + random.choice(Gamer.fruitsname) def main(): gamer = Gamer(100) # 最初の所持金は100 memento = gamer.createMemento() # 最初の状態を保存しておく # print(memento.__dict__) # debug for i in range(50): # ゲームの回数 print ("==== {}".format(i)) # 回数表示 print("現状:{}".format(gamer)) # 現在の主人公の状態表示 gamer.bet() print("所持金は{}円になりました。".format(gamer.getMoney())) if gamer.getMoney() > memento.getMoney(): print(" (だいぶ増えたので、現在の状態を保存しておこう)") memento = gamer.createMemento() # print(memento.__dict__) # debug elif gamer.getMoney() < memento.getMoney() / 2: print(" (だいぶ減ったので、以前の状態に復帰しよう)") gamer.restoreMemento(memento) time.sleep(0) print() if __name__ == '__main__': main() """ ==== 0 現状:[money = 100, fruits = []] 何も起こりませんでした。 所持金は100円になりました。 ==== 1 現状:[money = 100, fruits = []] フルーツ(おいしいリンゴ)をもらいました 所持金は100円になりました。 ==== 2 現状:[money = 100, fruits = ['おいしいリンゴ']] 所持金が増えました 所持金は200円になりました。 (だいぶ増えたので、現在の状態を保存しておこう) ==== 3 現状:[money = 200, fruits = ['おいしいリンゴ']] フルーツ(バナナ)をもらいました 所持金は200円になりました。 ==== 4 現状:[money = 200, fruits = ['おいしいリンゴ', 'バナナ']] 何も起こりませんでした。 所持金は200円になりました。 ==== 5 現状:[money = 200, fruits = ['おいしいリンゴ', 'バナナ']] 何も起こりませんでした。 所持金は200円になりました。 """