Dolphin Smalltalk の MVPアーキテクチャで BMI checker


id:sumim:20080923:p1 の続き。

MVC の進化形である VisualWorks のアプリケーションモデルに続き、MVP(Model-View-Presenter)にも興味を持ったので、ちょっとした騒ぎにもなったディスコン宣言から一転、このほどめでたく 復活することになった Dolphin Smalltalk を使って BMI checker を書いてみました。


MVP パターン他についてはファウラーのをうけたわかりやすいまとめが猪股さんのところに。


Dolphin Smalltalk は、マルチプラットフォーム向けの SqueakVisualWorks と違い、Win 専用の Smalltalk 処理系です。フリーで一部制限付き版のコミュニティ・エディションと、有償でフル版のプロ・エディションがあります。フル版だとダブルクリックアプリケーションが作れるみたいですが、Smalltalk やその IDEアーキテクチャパターンなどに触れて学ぶのにはフリー版でも問題なさそうです。なお、フリー版ユーザーからの寄付も受け付けているようです。


もともとは暫定ダイナブック向けの OS だった Smalltalk-72、76 から、XEROX の都合で“ラベル”だけ IDE に変えて登場した Smalltalk-80、その直系の子孫にあたる SqueakVisualWorks と違い、当初から IDE としての Smalltalk 処理系を意識して作られた…ということもあったのでしょうか。Dolphin は、Squeak はもちろん VisualWorks よりももっとずっと“IDE”として洗練されているように見えます。

どうしても Visual Studio と比べられる運命にある MS 寄りの CLR/H 勉強会(第38回 CLR/H勉強会〜オブジェクト指向デイ〜)では Squeak、あるいは VisualWorks だけだと、見た目やインテリセンスの使い勝手などのクオリティにおいていささか残念な第一印象を与えかねないので、その方面に限ってはこの Dolphin にがんばってアピールしてもらうことにいたしましょう。w


で、Dolphin での BMI checker ですが、確かに VisualWorks より書きやすい印象で、実際、コードもシンプルで済みます。二つのウインドウの表示と、両者におけるモデルの共有は次のようにしました。

a := BMIChecker show.
b := BMIChecker show.
b view position: a view position + ((a view width + 10) @ 0).
a subPresenters with: b subPresenters do: [:aSub :bSub | bSub model: aSub model]
右のウインドウの体重を 80kg → 90kg に変更

http://squab.no-ip.com/collab/uploads/61/bmicheckerdol1.png


左のウインドウにも変更が反映される

http://squab.no-ip.com/collab/uploads/61/bmicheckerdol2.png

Shell subclass: #BMIChecker
    instanceVariableNames: 'heightPresenter weightPresenter bmiPresenter'
    classVariableNames: ''
    poolDictionaries: ''
    classInstanceVariableNames: ''

BMIChecker >> bmiChanged
    | bmiValue fieldColor |
    bmiValue := weightPresenter value / (heightPresenter value ** 2).
    bmiPresenter value: bmiValue.
    fieldColor :=
        bmiValue < 18.5 ifTrue: [Color white] ifFalse: [
        bmiValue < 20 ifTrue: [Color yellow] ifFalse: [
        bmiValue < 30
            ifTrue: [Color red: 255 green: 153 blue: 0]
            ifFalse: [Color red]]].
    bmiPresenter view backcolor: fieldColor

BMIChecker >> createComponents
    super createComponents.
    heightPresenter := self add: NumberPresenter new name: 'height'.
    weightPresenter := self add: NumberPresenter new name: 'weight'.
    bmiPresenter := self add: NumberPresenter new name: 'bmi'

BMIChecker >> createSchematicWiring
    super createSchematicWiring.
    heightPresenter when: #valueChanged send: #bmiChanged to: self.
    weightPresenter when: #valueChanged send: #bmiChanged to: self

BMIChecker class >> resource_Default_view
    "Answer the literal data from which the 'Default view' resource can be reconstituted.
    DO NOT EDIT OR RECATEGORIZE THIS METHOD.

    "レイアウト情報は省略。ファイルイン用ファイル参照のこと。"


ファイルイン用の .cls ファイルはこちらに。


追記
id:propella さんの Dolphin の記事。