SSブログ

Mac用USBデバイス-101 Cocoaバインディングのテスト [Mac用USBデバイス工作]

今、これを東岡崎のビジネスホテルで書いている。仙台から半日かかった。やっぱり遠かった。
最近のビジネスホテルはインターネット接続できるところが一般的らしく、便利と言えば便利だけど僕は会社のローミングなんかの設定をしていないので仕事ができるわけではない。今回のホテルは、部屋は狭いけど温泉があって(ほんまかいな)朝食付きで4,980円と結構安い。

今日のセッションが夕方6時に終わって、夕食を食べようと思って駅前をぐるぐるした。あまり面白そうなところには行き着かなかったが、駅前の通りから一本入ったところにインド料理店があった。最近うちの家族には、知らない土地でインド料理屋を見つけると入らなければならないという不文律が存在しているらしい。つい先日も、伊東に家族旅行での帰りの昼食にわざわざ探してまで行った。

今日行ったお店の話は改めて。

5.3.5  テストプロジェクト

昨日までのやり方でちゃんと動作するかどうか確認するため、テストプロジェクトを作ってみる。確認のポイントは
  1. NSTreeControllerのサブクラスを作って異なる要素(異なるクラスのインスタンス)を追加する
  2. 追加できる要素の種類が追加ボタンに反映される
のふたつがちゃんと動作するかということ。追加は一番若い子要素だけに限定する。つまりNSTreeControllerの追加メソッドのうちaddChild:だけを使う、ということである。これは簡単化のためと、子供の追加は自分で判断できるが、姉妹の追加は親に訊かなければわからない、という状況が一般的だからである。

5.3.6  要素となるテスト用のクラス

異なるクラスのインスタンスを追加する、と言ってもいっぱい書くのが面倒なのであるクラスとそのクラスのサブクラスのインスタンスだとしよう。

なんでもいいんだけど親クラスはNodeと言う名前で、ExtraNodeとOtherNodeという二つのサブクラスを作ろう。つまり
@interface Node : NSObject {
    NSString        *name;
    NSMutableArray  *children;
}
そしてNodeのサブクラス
@interface ExtraNode : Node
@end

@interface OtherNode : Node
@end
の二つを定義しよう。
Nodeは次のメソッドを実装する。
- (id)init;
- (id)initWithName:(NSString *)aName;

- (BOOL)canAddExtra;
- (BOOL)canAddOther;
初期化メソッドは
- (id)init
{
    return [self initWithName:@"Root Node"];
}

- (id)initWithName:(NSString *)aName
{
    self = [super init];
    name = [aName retain];
    children = [[NSMutableArray alloc] init];
    return self;
}
なんていうもの。サブクラスの初期化は
@implementation ExtraNode
- (id)init
{
    return [super initWithName:@"Extra Node"];
}
@implementation OtherNode
- (id)init
{
    return [super initWithName:@"Other Node"];
}
としておく。

canAdd???メソッドは、子要素としてExtraNodeか、あるいはOtherNodeが追加できるかどうかを返す。

ここで
  • Nodeオブジェクトは子供としてExtraNodeとOtherNodeの両方を持つことができる
  • ExtraNodeはOtherNodeだけ
  • OtherNodeはExtraNodeだけを子要素とできる
とする。別に何でもいいんだけど、テストなので見分けられやすいようにこうしておく。

つまり、親クラスNodeの実装では
- (BOOL)canAddExtra
{
    return YES;
}

- (BOOL)canAddOther
{
    return YES;
}
として、ExtraNodeの実装では
- (BOOL)canAddExtra
{
    return NO;
}
と上書きして、OtherNodeの実装では
- (BOOL)canAddOther
{
    return NO;
}
を上書きする。

要素の追加や削除はキー値コーディングのメカニズムを使ってNSTreeControllerがかってにやることになる。そのためにchildrenというインスタンス変数をInterface Builderであとから設定する。

childrenやnameへのアクセサメソッドは全く書いてない。これもキー値コーディングを使ってランタイムが勝手に用意することになる。C++なんかのアクセス制御にうるさい言語を使っていてこういうのを見ると、何ともだらしないと言うか、ええかいな、と言う疑問を抱いてしまう。また、バインディングを使い慣れていないとコードを見ても何をしているのかわからない(何にもしてないようにしか見えない)、と言うことになりかねない。この辺は好き嫌いや趣味に合う合わないの分かれるところだろう。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。