OOP への道:if と別れる50の方法《07》The Java™ Tutorials の事例から

記事一覧if 篇for 篇配列 篇

Python.use(better) # OOP への道 《Python3.1, Jython2.5.0, IronPython2.6.x》
The Java™ Tutorials の事例から
#2: テンプレートによる抽象表現

《著》真樹育未・後藤いるか・小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第0版♪1988/10/12 ● 第1版♪1993/05/23 ● 第2版♪2003/05/25

■ 概要

if/switch への未練を断ち切るのは容易ではありません。

伝統的なC言語風の for 文や悪名高い switch 文、配列の呪縛から解かれ、オブジェクト指向プログラミング〔OOP〕の醍醐味を堪能するための準備を行います。

The if-then-else Statement

》作業中です《

class TemplateDemo(object):
    def __init__(self, keys, values, default, cond):
        self.keys    = keys
        self.values  = values
        self.default = default
        self.cond    = cond
        
    def index(self, s):
        for n, e in enumerate(self.keys):
            if self.cond(s, e):
                return self.values[n]
        else:
            return self.default

def example():
    ## ----------------------------------------
    print("#", "-"*20, "HexDemo")
    demo = TemplateDemo(
        "0123456789ABCDEF",
        range(16),
        -1,
        lambda s, e: s == e,
        )
    for e in "0123456789ABCDEF@":
        print("Hex = %2d"%demo.index(e), ":", e)

    ## ----------------------------------------
    print("#", "-"*20, "IfElseDemo")
    demo = TemplateDemo(
        [90, 80, 70, 60],
        "ABCD",
        "F",
        lambda s, e: s >= e,
        )
    for e in range(0, 101, 10):
        print("Grade = %s"%demo.index(e), ":", e)

HexDemoとIfElseDemoとの違いを、インスタンス属性ごとに検証します。

  • インスタンス属性 .keys に対して、実引数として、文字列"0123456789ABCDEF"と数列[90, 80, 70, 60]とが与えられます。これらに共通するのはともにシーケンスであり、これらの相違は各要素が文字か数かです。
  • インスタンス属性 .values に対して、実引数として、数列 range(16)と文字列"ABCD"とが与えられます。やはり、シーケンスとしては同じですが、各要素は文字と数とで異なります。
  • インスタンス属性 .default に対して、実引数として、-1と"F"とが与えられます。これらは数と文字とで異なりますが、単一のオブジェクトということでは同じです。
  • インスタンス属性 .cond に対して、どちらも bool をリターン値とする関数オブジェクトです。


テンプレートとして規定された、抽象メソッド index の役割に着目すると、

  • 任意のシーケンスself.keysから各要素eを参照するとともに、
  • 条件式self.cond(s, e)を使って判定を行うとともに、
  • 任意のシーケンスself.valuesから取り出した要素をリターン値とすることと、
  • 条件を満たさない場合には、規定値をリターン値にすると、

という、各要素の型には依存しない抽象表現になっているのが分かります。これらの条件を満たすなら、どのような場合にも対処できます。それ以外の場合には、何も保証していません。


これを実行すると、次のような結果が得られます。

>>> example()
# -------------------- HexDemo
Hex =  0 : 0
Hex =  1 : 1
Hex =  2 : 2
Hex =  3 : 3
Hex =  4 : 4
Hex =  5 : 5
Hex =  6 : 6
Hex =  7 : 7
Hex =  8 : 8
Hex =  9 : 9
Hex = 10 : A
Hex = 11 : B
Hex = 12 : C
Hex = 13 : D
Hex = 14 : E
Hex = 15 : F
Hex = -1 : @
# -------------------- IfElseDemo
Grade = F : 0
Grade = F : 10
Grade = F : 20
Grade = F : 30
Grade = F : 40
Grade = F : 50
Grade = D : 60
Grade = C : 70
Grade = B : 80
Grade = A : 90
Grade = A : 100

ここまで来ると、switch 文の代用表現として、辞書 dict が有効になるのが分かるでしょう。実際に、dict.get などは、これらの抽象メソッドと同様の処理を行っているのが分かります。


これで、OOP への道を探求する「準備」は整いました。次回から、いよいよ「佳境」に入ります。

Tips

》作業中です《

Last updated♪2009/07/26