ロゴ
ホーム 提案事例 Obxetoについて 問い合わせ

1.Adapter Pattern

1.1 特徴

Adapter Patternは、異なるインタフェースを持つクラス同士をAdapterによって適合させるDesign Patternです。

1.2 サンプルプログラムを書いた目的

なぜAdapter Patternを使うのかというと、将来の変更に対して柔軟に対応できる設計であることが主な理由です。
  • 利用者(Client)によて使用されるクラス(Adaptee)が変更される。
  • 利用者(Client)要求するインタフェース(Target)が変更される。
このどちらの場合もコードの修正はAdaper止まりです。この点がはっきり理解できるサンプルを目指しました。

1.3 変更に伴って修正されるクラス

利用者が要求するインターフェース(Target)が変更された場合、その変更はAdapterのrequiredMethod()の 修正に止まりAdapteeには影響しない。一方、Adapteeが変更されてもその影響はAdaperのsuperクラスのfixedMethod() 呼び出しの修正に止まり、ClientとTargetに及ばない。 この設計はオープン・クローズドの原則に適合している。

図1-1:クラス図

  • Client:利用者のクラス
  • Target:利用者が要求するインターフェース
  • Adapter:Adapteeのインタフェースを変換してTargetに適合させるクラス
  • Adaptee:利用者(Client)が必要とする機能を持つが、インタフェースが異なるクラス

1.4 サンプルプログラム

Targetが変更された場合の修正箇所を青、Adapteeが変更された場合の修正箇所を赤で示した。
        #import <Foundation/Foundation.h>

        @protocol Target
        - (void)requiredMethod;
        @end 

        @interface Adaptee : NSObject
        @end
        @implementation Adaptee
        - (void)fixedMethod
        {
            NSLog(@"fixedMethod");
        }
        @end

        @interface Adapter : Adaptee<Target>
        @end
        @implementation Adapter
        - (void)requiredMethod
        {
            [super fixedMethod];
        }
        @end

        @interface Client : NSObject
        - (void)callRequiredMethod;
        @end
        @implementation Client
        - (void)callRequiredMethod
        {
            id<Target> target;
            
            target = [[[Adapter alloc] init] autorelease];
            [target requiredMethod]; 
        }
        @end

        int main(int argc, const char * argv[])
        {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
            
            Client *client;
            client  = [[[Client alloc] init] autorelease];
            
            [client callRequiredMethod];
           
            [pool drain];
            return 0;
        }
     

参考文献: Deign Pattern by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides