Double Dispatch の実装

要件/目的: Double Dispatch のサンプルプログラムを書いてみる
自己アピール: プログラムのメンテナンス性を高める1つの手法
コメント: こんなんで良いのかな?

何となく、ふと思い出したので実際に書いてみました。適当な題材がないかなと探してみたところ、以下のじゃんけんを模倣しました。
窓際プログラマーの独り言:ダブルディスパッチ

#!/bin/env python

"""
    This is an sample for double dispatch with python.
    I want to know how to maintain a program effectively.
"""

class JyankenHand():
    def __init__(self):
        """This is an abstract class."""
        if self.__class__ is JyankenHand:
            raise TypeError, ("JyankenHand is an abstract class.")
        self.dic = {'goo': 'You\'re Goo!\n--result ',
                    'choki': 'You\'re Choki!\n--result ',
                    'paa': 'You\'re Paa!\n--result '}

    def JyankenFight(self, hand):
        return self.fight(hand)

    def JyankenResultFromGoo(self, hand):
        return hand.fromGoo()

    def JyankenResultFromChoki(self, hand):
        return hand.fromChoki()

    def JyankenResultFromPaa(self, hand):
        return hand.fromPaa()

class Goo(JyankenHand):
    def fight(self, hand):
        return "I'm Goo!\n" + self.JyankenResultFromGoo(hand)

    def fromGoo(self):
        return self.dic['goo'] + "Goo Draw\n"

    def fromChoki(self):
        return self.dic['goo'] + "Choki Lose\n"

    def fromPaa(self):
        return self.dic['goo'] + "Paa Win\n"

class Choki(JyankenHand):
    def fight(self, hand):
        return "I'm Choki!\n" + self.JyankenResultFromChoki(hand)

    def fromGoo(self):
        return self.dic['choki'] + "Goo Win\n"

    def fromChoki(self):
        return self.dic['choki'] + "Choki Draw\n"

    def fromPaa(self):
        return self.dic['choki'] + "Paa Lose\n"

class Paa(JyankenHand):
    def fight(self, hand):
        return "I'm Paa!\n" + self.JyankenResultFromPaa(hand)

    def fromGoo(self):
        return self.dic['paa'] + "Goo Lose\n"

    def fromChoki(self):
        return self.dic['paa'] + "Choki Win\n"

    def fromPaa(self):
        return self.dic['paa'] + "Paa Draw\n"


# Main - Jyanken Poi -
if __name__ == "__main__":
    # initialize
    h1 = Goo()
    h2 = Choki()
    h3 = Paa()

    # test-phase 1
    print h1.JyankenFight(h2)
    print h2.JyankenFight(h3)
    print h3.JyankenFight(h1)

    # test-phase 2
    print h3.JyankenFight(h3)
    print h3.JyankenFight(h2)
    print h2.JyankenFight(h1)

実行結果。

$ ./jyanken.py
I'm Goo!
You're Choki!
 --result Goo Win

I'm Choki!
You're Paa!
 --result Choki Win

I'm Paa!
You're Goo!
 --result Paa Win

I'm Paa!
You're Paa!
 --result Paa Draw

I'm Paa!
You're Choki!
 --result Paa Lose

I'm Choki!
You're Goo!
 --result Choki Lose