2011-11-16 39 views
6

所以我一直在閱讀關於Objective-C的模板方法,我正試圖理解它們的特殊之處。根據我的理解,Base類中的任何方法都可能被覆蓋,super可以被調用?那麼模板方法不僅僅是覆蓋基類中的方法嗎?Objective-C - 模板方法模式?

如果我錯了,你能解釋一下模板方法模式是什麼,你能提供一個例子嗎?

+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類非常不同的步驟。

這種模式有一些變化;例如,某些步驟也可以具體定義。在這個例子中,eatLunch()可以在Life類中具體定義;這意味着子類不會改變這種行爲。

如果你有一個相對複雜的算法可以用不同的方式實現,這個模式很有意義。

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

我莫名其妙在我的回答中錯過了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可以被調用?那麼模板方法不僅僅是覆蓋基類中的方法嗎?

是的,這只是重寫基類方法而已。模板方法是一種實現算法的方法,其中某些步驟是子類依賴的。例如,考慮一個基本方法,它有三個主要步驟,f1,f2和f3。每個步驟都包含許多陳述。這裏f1和f3在所有子類中都是相同的,但是f2是子類依賴的。那麼在這裏做什麼?您可以覆蓋f1和f3的子類複製語句中的整個方法,但這太浪費了。所以你只在子類中提供f2。這樣你就可以在基類中定義算法(執行f1,然後執行f2,然後執行f3),但爲子類(f2)提供覆蓋鉤子。注意,基類中的模板方法是final的,所以子類不能改變算法,例如它不能改變f1,f2和f3的順序,兩個子類都不能省略步驟f1,f3。

簡而言之,模板方法模式不僅僅是重寫,它是使用繼承來處理一些特定的情況。這不是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:,那麼最終可能會多次不必要地重畫。

事實上,你應該嘗試使你想要在子類中覆蓋模板方法的每個方法。這樣可以減少在重寫時調用基類實現並使調試更簡單的問題。你可以在基類中放置一個斷點,而不是在子類中重載每個方法。