Mac用USBデバイス-105 Cocoaバインディングテストのまとめ [Mac用USBデバイス工作]
昨日のテストアプリでNSTreeControllerの要素として、場合によって異なるクラスのインスタンスを追加することができるかどうかを試してみた。テストアプリはNSTreeControllerのサブクラスを作って利用する例にもなった。確かに書かなければならないコードの量は、同じことを専用のコントローラクラスとターゲット/アクションだけで書く場合に比べて(実際には書いてないけど)劇的に少ないということはわかった。
それに比べてNSDocumentはなんて簡単なんだろう、何にもしていないみたいだ、と思っていた。ところがCocoaバインディングではさらになにもしない。このテストプロジェクトのNodeのコードなんて構造変化に対応するための記述がまったく何もない。もちろんテストではなく実際のアプリでは構造が出来上がったあとそれに対してやるべき仕事があるのが普通だけど、構造の編集にまつわる部分の記述はまったく不要になる。古いMacOSと比較するまでもなく、専用のコントローラを介したターゲット/アクションだけで編集作業を記述することに比べてもコードの量が少ないだけでなく、コード自体が非常にスタティックに見える。
具体的に説明する。Nodeオブジェクトには
Cocoaバインディングを使うことで、インスタンス変数の編集はNSOutlineViewを通じてユーザの操作が反映する形で行われて、編集作業のコードを書く必要がなくなってしまった。ユーザが編集を完了したと考えた時点でNodeオブジェクトのツリーは出来上がっている。
もしバインディングにまつわる部分にバグが発生しなければ、こんなにデバグしやすいことはない。なにせいにしえのFORTRANのプログラムのように一直線の記述しかない。古いMacOSでテキストボックスに文字列を入力しようとするとフリーズするバグにずいぶん悩んだことがあった。深いswitch/case文の入れ子の中で複数のイベントを処理をするとき、ある順番だけcase文の記述が抜けてたためだった。デバガを何度もまわしてcase文の振り分けを追っていってやっとわかった。場合分けが発生してそれがユーザの動作に依存するようなコードはデバグが非常に難しい。
Cocoaバインディングを使えば、そういう部分の記述はすっぱり書かなくてよくなる。
これはすごいことだ。
大勢のプログラマが参加する大きなアプリではまた違った問題が出てくるだろうけど、ひとりでしこしこ書いている特殊用途用のアプリのプログラマにとって、Cocoaバインディングを使わない手はない。
5.3.15 テストのまとめ
初めてMac OS Xのアプリを書き始めた頃、古いMacOSの時代に比べて、NSDocumentを使ったドキュメントスタイルのアプリはなんて簡単なんだろう、と思った。少なくとも古いMacOSでは、ちゃんとしたドキュメントアプリなんか書く気がしなかったし、ほんのちょっとした、例えばユーザがウィンドウの位置やサイズを変更したいときにそれに対応するようにコードを書くぐらいのことでも、微妙な順番や無視できない処理に神経を使いながら膨大な量のコードを書かなければならなかった。このために非常にたくさんの場合分けを持つダイナミックなコードを操る必要があった。それに比べてNSDocumentはなんて簡単なんだろう、何にもしていないみたいだ、と思っていた。ところがCocoaバインディングではさらになにもしない。このテストプロジェクトのNodeのコードなんて構造変化に対応するための記述がまったく何もない。もちろんテストではなく実際のアプリでは構造が出来上がったあとそれに対してやるべき仕事があるのが普通だけど、構造の編集にまつわる部分の記述はまったく不要になる。古いMacOSと比較するまでもなく、専用のコントローラを介したターゲット/アクションだけで編集作業を記述することに比べてもコードの量が少ないだけでなく、コード自体が非常にスタティックに見える。
具体的に説明する。Nodeオブジェクトには
- (id)init; - (id)initWithName:(NSString *)aName; - (void)dealloc; - (BOOL)canAddExtra; - (BOOL)canAddOther; - (BOOL)canRemove; - (NSString *)description;これだけのメソッドしか実装していない。記述すべきコードにはオブジェクトの初期化initなどとcanAdd...という属性定義、あとは編集後の処理としてdescriptionによるオブジェクト構造の表示だけしかなく、nameやchildrenなどのインスタンス変数を操作するメソッドは記述していない。Cocoaバインディングを使わなければ、おそらくこれ以外に
- (NSString *)name; - (void)setName:(NSString *)newName; - (id)childAtIndex:(NSUInteger)index; - (void)addChild:(id)child atIndex:(NSUInteger)index; - (void)removeChildAtIndex:(NSUInteger)index;などを実装し、さらにこのメソッドをNodeオブジェクトに投げて構造を操作するコントローラを作る必要がある。つまり
- nameインスタンス変数の書き換え
- children変数の中の子要素の指定
- children変数への子要素の追加、削除
Cocoaバインディングを使うことで、インスタンス変数の編集はNSOutlineViewを通じてユーザの操作が反映する形で行われて、編集作業のコードを書く必要がなくなってしまった。ユーザが編集を完了したと考えた時点でNodeオブジェクトのツリーは出来上がっている。
もしバインディングにまつわる部分にバグが発生しなければ、こんなにデバグしやすいことはない。なにせいにしえのFORTRANのプログラムのように一直線の記述しかない。古いMacOSでテキストボックスに文字列を入力しようとするとフリーズするバグにずいぶん悩んだことがあった。深いswitch/case文の入れ子の中で複数のイベントを処理をするとき、ある順番だけcase文の記述が抜けてたためだった。デバガを何度もまわしてcase文の振り分けを追っていってやっとわかった。場合分けが発生してそれがユーザの動作に依存するようなコードはデバグが非常に難しい。
Cocoaバインディングを使えば、そういう部分の記述はすっぱり書かなくてよくなる。
これはすごいことだ。
大勢のプログラマが参加する大きなアプリではまた違った問題が出てくるだろうけど、ひとりでしこしこ書いている特殊用途用のアプリのプログラマにとって、Cocoaバインディングを使わない手はない。
2010-05-27 22:33
nice!(0)
コメント(0)
トラックバック(0)
コメント 0