OOP への道:if と別れる50の方法《05》ジャンケン問題, double-dispatch
Python.use(better) # OOP への道 《Python3.1, Jython2.5.0, IronPython2.6.x》
ジャンケン問題, double-dispatch
■ 概要
if/switch 文は多くの問題を抱え、OOP を実践するときの「障害」になります。
伝統的なC言語風の for 文や悪名高い switch 文、配列の呪縛から解かれ、オブジェクト指向プログラミング〔OOP〕の醍醐味を堪能するための準備を行います。
■ 関連記事
- Java プログラマーのための Python 導入ガイド
- 例題で学ぶ Jython/Swing デザインパターン《Jython2.5》改訂版
- ゲームに学ぶ Jython/Swing フレームワーク《Jython2.5》改訂版
- IronPython で学ぶ WPF プログラミングの世界《IronPython2.6》改訂版
double-dispatch
《Note》Smalltalk との出会いで印象深いもののひとつが double-dispatch です。単純なメカニズムでありなが、その用途は広く、OOP の神髄を垣間見る思いがしたものです。
■ double-dispatch
class Player(object):
def __init__(self, id):
self.id = id
def __repr__(self):
return "%s(%s)"%(self.__class__.__name__, self.id)
def next(self):
self.hand = (PlayerG, PlayerC, PlayerP)[randint(0, 2)]()
return self.hand
def judge(self, player):
return self.hand.judge(player.hand)
■ 抽象クラス
抽象クラスでは、具象クラスに共通するプロトコルを規定します。
class Hand(object): def __repr__(self): return "(%s)"%(self.__class__.__name__) def judge(self, player): return eval("player.judgeFrom%s(self)"%self.__class__.__name__)
メソッド judge の意味(意義)を、メッセージ送受信に沿って説明します。
送信者 player から、メッセージ judge を受信したときには、player の手は3つの選択肢のひとつに確定しています。しかし、それが具体的に何かを受信者 self は、知る必要はありません。その代わり、自分 self がどの手を選択したかは、メッセージを受信したときにはすでに確定しています。
たとえば、R(rock) を選択したなら、それは次のように、
def judge(self, player):
return player.judgeFromPlayerR(self)
送信者 player に対して、受信者 self から、メッセージ judgeFromPlayerR が返信されます。
■ 具象クラス
具象クラスでは、勝者になるプレーヤー self,player か、引分を意味する None をリターン値にします。
class PlayerR(Hand): def judgeFromPlayerR(self, player): return None def judgeFromPlayerP(self, player): return player def judgeFromPlayerS(self, player): return self class PlayerP(Hand): def judgeFromPlayerR(self, player): return self def judgeFromPlayerP(self, player): return None def judgeFromPlayerS(self, player): return player class PlayerS(Hand): def judgeFromPlayerR(self, player): return player def judgeFromPlayerP(self, player): return self def judgeFromPlayerS(self, player): return None
》作業中です《
何が問題か:N人ジャンケンへの道
すべての if 文は消滅しました。しかし、これは望ましい結果でしょか。伝統的な if 文による解法と比べて、記述したコードの量はむしろ増えています。費用対効果を考えると、このアプローチは得策でないとも言えます。確かに、2人で対戦する場合はそのとおりですが、これが、3人以上、そして一般にn人で対戦する場合になると、その状況は一変します。
Tips
》作業中です《