BankAccount
ここで登場する BankAccount の例の直接の出典は、SELF の Demo.snap 中のチュートリアルのものです。BankAccount を継承した StockAccountを含むこの例では、短いコードながらもインスタンス変数(スロット)へのアクセス、継承(委譲)、多態性などオブジェクト指向プログラミングの特色や、(言語によっては)オブジェクトの動的な振る舞いを観察するのによいサンプルだと思い、主に自分にとって新しい言語の学習時に気に入って使っています。言ってみれば、オブジェクト指向言語向けの Hello, World! 的、あるいはオブジェクト指向を公言する言語に対する(相手によってはちょっと悪意を込めた)“踏み絵”的な存在ですね。
おおもとのはある種の古典で、いろいろなバリエーションや拡張、もしくは、同名でも別の趣旨のものなど多数存在するようです。--sumim
いろいろな言語でBankAccount
参考:
解説
BankAccount のおおまかな流れ
※ 変数名などは各ページのコードで用いているものと必ずしも一致しません。
BankAccount (クラスベースなら、そのインスタンス)は dollars という値スロット(クラスベースならインスタンス変数)を持ち、それへの外部からの直接のアクセスを許します。また、deposit: x、withdraw: x というメッセージを受け、dollars の値に x を足したり、dollars から引いたりできます。ただし、x > 0、dollars はマイナスにならないものとします。ここで dollars は ballance のほうが相応しい(Self の Web 版チュートリアルでもそうなっていて、多くの BankAccount でもそうなっている)のですが、最初の Io の例で Self の Demo.snap にならって dollars としてしまった手前、ここでは dollars に統一しています。
プロトタイプベースの場合 BankAccount が定義したメッセージに応答できるかどうかをチェックし、続けて BankAccount をプロトタイプとする myAccount を作り同様のデモを行ないます。このとき、プロトタイプのメソッドを利用していても、プロトタイプの値スロットには影響を与えていないことを確認します。クラスベースならインスタンスで動作確認だけします。
次に、BankAccount をプロトタイプに(クラスベースならスーパークラスにして) StockAccount を作ります。StockAccount は株数と株単価をそれぞれ束縛する numShares、pricePerShare という二つの値スロットを(BankAccount に追加するかたちで)持っています。StockAccount は、StockAccount >> #dollars をオーバーライドし、自らの株の総額の返答にこれを代えます。dollars: x についても同じで、pricePerShare から見積もった株数に換算し、numShares に新しい値を束縛します。
StockAccount は、#deposit: 、#withdraw: についてはこれらを BankAccount から継承し自分ではメソッドを持ちません。それぞれの定義の中で用いられている #dollars 、#dollars: で多態性を示すことによって、deposit: x 、withdraw: x というメッセージを受けたときに期待される動作(numShares の更新)を行ないます。プロトタイプベースなら myStock としてクローンし、myAccount と同様のチェックをするのもよいでしょう。クラスベースなら myAccount に StockAccount のインスタンスを束縛しその動作を確認します。
これだけだと、組み込みによる継承を区別できないので、BankAccount >> #deposit 、BankAccount >> #withdraw: を書き換えて、例えば、パラーメータとして与えられた x を無条件で目減りさせて処理をおこなうような変更(手数料差し引きなどを想定するとよいでしょう)を加えたとき、ただちにそれがクローン(サブクラスのインスタンス)に波及するかを確かめることも場合によっては、しています。
--sumim
BankAccount の評価のポイント
もともとがオブジェクト指向のチュートリアルで、さらにはプロトタイプベースの Self 向けに“有利”に作られた問題なので、ベースのパラダイムを異にする言語やオブジェクトシステムによっては(たとえオブジェクト指向を標榜していても)、ここで期待される機能を忠実に再現できなかったり、それをしようとすると冗長になったり、トリッキーさを強いられることはたぶんにあろうかとは思います。が、たとえこうした問題領域が得意分野でないとしても、ある程度満足できるところまで対応できることが言語の潜在的なパワーだろうと個人的には信じているので、期待した振る舞いをさせられない場合、弱っちい言語だ…という印象を持ってそうしたニュアンスのコメントしてしまっているかもしれません(^_^;)。各言語やオブジェクトシステムのファンにおかれましてはこの点、ご容赦あれかし。
他に個人的なチェックポイントとしては、
- 委譲(継承)先の指定、値スロット(インスタンス変数)の宣言、メッセージへの応答以外の記述をどこまで省けるか?
- スロットへのアクセスに、スロット名と同じかそれに非常に近いメッセージやセレクタが使えるか?
- プロトタイプ(あるいはクラス、トレイト)の変更が即座にクローン(インスタンス、サブクラスインスタンス)に波及するか?
などを見て、自分好みの言語かどうかを判断しています。
--sumim
このページを編集 (4445 bytes)
|
以下の 2 ページから参照されています。 |
This page has been visited 5500 times.