2008-04-26

Objective-Cの手習い:Adapterパターン

今度は、また『Java言語で学ぶデザインパターン入門』からAdapterパターン。

Wrapperとも呼ばれるように、別クラスを被せるようにデザインしてインターフェイスを替えてあげるもの。Adapterを実現する方法として

  • 継承を利用する方法
  • 委譲を利用する方法

がある。Objectivel-Cでは、他の言語と同様に前者については継承とProtocol(JavaでいうInterface)を利用して実現、後者についてはProtocolとインスタンス変数としてBannerを持つことで実現できる。

一般的にはC++のような静的な型付けが強い言語では前者、Smalltalkのような動的な言語では後者が採用されるケースが多い。今回は後者のパターンで書いてみる。

ただし、Objetive-Cではカテゴリという機構があるので後者をより簡易に実現できる非形式Protocolが利用される。これは、オリジナルのクラス自体を拡張させて新たなインターフェイスを持たせることができるもの。

BannerクラスはそのままJavaのコードを移植して以下のような宣言になる。

Banner.h

@interface Banner : NSObject {
    NSString* i_string;
}
-(id)initWithString:(NSString*) strg;
-(void)showWithParen;
-(void)showWithAster;
@end

今回は、非公式Protocolを利用する。これは、Objective-Cのカテゴリの機能を使ったもの。宣言部は以下のようになる。

Banner+Print.h

@interface Banner(Print)
-(void) printWeek;
-(void) printStrong;
@end

カテゴリとはObjective-Cらしいところで、既存のクラス(この場合、Bannerクラス)に新たなメソッドを動的に追加できるのだ。「動的」とは、Bannerクラスのソースコードをなくオジェクトモジュールしかない場合も、Objective-Cではこの機構を新しいメソッドをBannerクラスに追加していけるということ。

またこの機構を使った場合の、ソースのファイル名は慣習的に"元のクラス名+カテゴリ名"とするようだ。

で、メイン関数での処理は以下のようになる。

id p = [[Banner alloc] initWithString:@"Hello"];
[p autorelease];
[p printWeek];
[p printStrong];

Bannerクラスがオリジナルでは持っていないはずのprintWeekやcode>printStrongなどのメソッドをBannerクラスで受けていることに注目。最も『Java言語で学ぶデザインパターン入門』で述べられているようにこのコンテキストでのプログラマの意図を明確にするためにPrintというインターフェイスで受けたければ非形式でないProtocolを利用すればよい。

0 件のコメント:

コメントを投稿