2011-11-16 3 views
6

私はObjective-Cのテンプレートメソッドについて読んできました。私はObjective-Cの特別なことを理解しようとしています。私の理解から、Baseクラスのメソッドはすべてオーバーライドされ、スーパーは呼び出すことができますか?テンプレートメソッドは、基本クラスのメソッドをオーバーライドする以上のものですか?Objective-C - テンプレートメソッドパターン?

私が間違っている場合、template-method-patternが何であるか説明していただけますか?例を挙げてください。

+1

デザインパターンについて聞いたことがありますが、「それほど多くはありません」と思うと、ほとんど正しいです。それらの多くは明らかです。 – morningstar

答えて

21

はい、テンプレートパターンは基本クラスのメソッドをオーバーライドするだけのものです。

アルゴリズムの輪郭が具体的に定義されている場合にテンプレートパターンを使用できますが、アルゴリズムのステップは抽象的なままです。これは、ステップが異なる方法で実装できることを意味します。しかし、アルゴリズムの一般的な概要は変わるとは考えられません。

私はその場で作成した例は:

class Life { 

    public method goThroughTheDay(){ 
    goToWork(); 
    eatLunch(); 
    comeBackHome(); 
    programABitMore(); 
    } 
    abstract method goToWork(); 
    abstract method eatLunch(); 
    abstract method comeBackHome(); 
    abstract method programABitMore(); 
} 

class GoodLife extends Life { 
    //override all the abstract methods here 
} 

//The client application 
Life life = new GoodLife(); 
life.goThroughTheDay(); 

基本的に、日はダウンを実行することが期待されている方法は、具体的にはライフクラスで定義されます。ただし、プロセスの詳細はサブクラス(GoodLife)によって処理されます。 GoodLifeクラスは、ToughLifeクラスとはまったく異なるステップを実装します。

このパターンにはいくつかのバリエーションがあります。例えば、いくつかのステップを具体的に定義することもできる。この例では、LifeクラスでeatLunch()を具体的に定義できます。サブクラスがこの動作を変更するとは予想されません。

パターンは、さまざまな方法で実装できる比較的複雑なアルゴリズムを使用している場合は非常に意味があります。

======================================

I何とか私の答えでObjective-Cでその部分を逃した。ここでは、Objective-Cでどのように見えるかです:

@interface Life : NSObject 

- (void) goThroughTheDay; 

- (void) goToWork; // Abstract 
- (void) eatLunch; // Abstract 
- (void) comeBackHome; // Abstract 
- (void) programABitMore; // Abstract 

@end 

@implementation Life 

- (void) goThroughTheDay { 

    [self goToWork]; 
    [self eatLunch]; 
    [self comeBackHome]; 
    [self programABitMore]; 
} 

- (void) goToWork { [self doesNotRecognizeSelector:_cmd]; } 
- (void) eatLunch { [self doesNotRecognizeSelector:_cmd]; } 
- (void) comeBackHome { [self doesNotRecognizeSelector:_cmd]; } 
- (void) programABitMore { [self doesNotRecognizeSelector:_cmd]; } 

@end 

@interface GoodLife : Life 

@end 

@implementation GoodLife 

- (void) goToWork { NSLog(@"Good Work"); } 
- (void) eatLunch { NSLog(@"Good Lunch"); } 
- (void) comeBackHome { NSLog(@"Good Comeback"); } 
- (void) programABitMore { NSLog(@"Good Programming"); } 

@end 

のObjective-Cは、抽象クラスのサポートを内蔵していないので、私はdoesNotRecognizeSelector:メソッドを使用して、その周りに働きました。抽象クラスの詳細は& Objective-Cはhereです。

+0

質問は特にObjective-C実装を求めていますが、Javaのように見えます。あなたは良いObjective-Cの同等物を提供できますか?私が知る限り、Objective-Cには抽象的なキーワードや同等の概念はありません。答えとしての –

+0

-1がObjective-Cコンテキストで設定されていません。 – matm

+0

できれば、私も-1です。 –

1

私の理解から、Baseクラスのどのメソッドもオーバーライドされ、superを呼び出すことができますか?テンプレートメソッドは、基本クラスのメソッドをオーバーライドする以上のものですか?

はい、これは基本クラスのメソッドをオーバーライドするだけです。テンプレートメソッドは、いくつかのステップがサブクラスに依存するアルゴリズムを実装する方法です。たとえば、3つの主要なステップf1、f2、およびf3を持つBaseのメソッドを考えてみましょう。各ステップにはいくつかのステートメントが含まれています。ここで、f1とf3はすべてのサブクラスで同じですが、f2はサブクラスに依存します。だからここで何をすべきか? f1とf3のステートメントをコピーするサブクラスでメソッド全体をオーバーライドすることはできますが、それは無駄です。したがって、サブクラスではf2のみを提供します。そして、これは基本クラスでアルゴリズムを定義する(f1を実行してからf2を実行し、次にf3を実行する)が、サブクラス(f2)にはオーバーライドフックを提供する方法です。基本クラスのテンプレートメソッドは最終的なので、サブクラスはアルゴリズムを変更できないことに注意してください。 f1、f2、f3の順番を変更することはできず、いずれのサブクラスもf1、f3のステップを省略することはできません。簡潔に言えば、Template Methodsパターンは単にオーバーライドするだけではなく、いくつかの特定の状況を処理するために継承を使用しています。これはObj-C固有のものではなく、Obj-C固有のものを提供することはできません。

  1. Design Patterns book by GoF
  2. Head First Design Patterns
  3. Wikipedia article on Template Method

をとチュートリアル/記事のトンは、ウェブ上でもあります。このパターンについての全体的なアイデアを得るために、私は次のことをお勧めします。基本的な考え方はObj-Cに依存しません。

2

私はもっとObjective-C固有の回答を与えるべきだと思いました。あなたはリンゴのココアで使用されているテンプレートメソッドについて読むことができますCocoa Design Patterns pages。この例は、drawRect:テンプレートメソッドです。他のテンプレートメソッドと同様に、自分で直接テンプレートメソッドを呼び出すことはありません。それはsetNeedsDisplayによって呼び出されます。これは、フレームワークが図面を最適化できるようにすることです。 drawRect:を自分で直接呼び出すと、何度も再描画が不要になることがあります。

実際、サブクラスでオーバーライドするすべてのメソッドをテンプレートメソッドにするようにしてください。これにより、オーバーライド時に基本クラスの実装を呼び出す必要があるかどうかを知る問題が軽減され、デバッグが容易になります。サブクラス内のすべてのオーバーライドされたメソッドではなく、基本クラスにブレークポイントを置くことができます。

関連する問題