Oh 脳《136》続・クラス指向からオブジェクト指向へ

記事一覧Oh 脳: after ZERO《其之佰参拾陸》

続・クラス指向からオブジェクト指向

《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2009/10/30

セミナーの枕で紹介した小ネタ集です。息抜きや話題作りにどうぞ (^.^)

セミナー通信@2009/10/30》

同様の問い合わせがいくつか寄せられたので、
前回の余録として、以下を追記しておきます。


... zap ...
次に示す2つのテストケースの違いが分かりますか。

# testcase: 1 -- for class-base
s = Stack(); s
s.push("A"), s
s.push("B"), s
s.pop(), s
s.pop(), s
s.pop(), s

# testcase: 2 -- for object-base
s = Stack(); s
s.push("A"), s
s.push("B"), s
s.pop(), s
s.pop(), s
s.pop(), s

ちなみに、どちらを実行しても、次のように同じ結果になります。

>>> s = Stack(); s

>>> s.push("A"), s
(None, ['A'])
>>> s.push("B"), s
(None, ['A', 'B'])
>>> s. pop(), s
('B', ['A'])
>>> s.pop(), s
('A', )
>>> s.pop(), s
IndexError: pop from empty list
(None, [])

これらはスタック操作を扱ったものですが、
テストケース自身に違いはなく、その違いはテストケースの対象です。

  • テストケース1では、クラスを使って実現したもの(class-base)を、
  • テストケース2では、関数を使って実現したもの(object-base)を、

それぞれの対象にしています。

    class Stack(list):    # testcase: 1a -- for class-base
        ...
    class Stack(object):  # testcase: 1b -- for class-base
        ...
    def Stack():          # testcase: 2 -- for object-base
        ...

OOP を実践するのに「クラスは必須ではない」ことを例示するために、
同じテストケースを再利用するという制約を課してあるので、
クラス名/メソッド名を「意図的に」同じ Stack に統一しました。
目的(what)は同じでも、手段(how)だけが異なるという、
情報隠蔽の原則に沿ったアプローチを「体感」してもらうためです。


また、テストケース 1a/1b の違いは「継承/委譲」によるものです。
継承は、white-box アプローチとも呼ばれ、
その機能を拡張するのは容易ですが、その反面、
情報隠蔽の原則に反するコードによる汚染を防ぐために、
多くの労力を余儀なくされることを覚悟しなければなりません。


委譲は、black-box アプローチとも呼ばれ、
情報隠蔽の原則に反するコードによる汚染を未然に防げますが、
その反面、継承と比べて、機能を拡張するのに少し手間が掛かります。


クラスライブラリー/アプリケーションフレームワークを前にして、
利用者(SE)と提供者(プログラマー)との立場の違いもあるので、
一概に、どちらが優れているとは言えず、
これらのトレードオフ問題について、熟慮する必要があります。


... zap ...
クラスを使ったプログラミングができるからと言って、
かならずしも OOP を理解できているとは限りません。


詳細は、以下を参照してください。


OOP を正しく理解できていれば、それを実践する方法は多種多様です。
この他にも、高階関数クロージャーを利用するなどなど、
受講者のみなさんも、自分なりのアプローチを工夫してください。

Last updated♪2009/10/29