所以我一直在閱讀關於Objective-C的模板方法,我正試圖理解它們的特殊之處。根據我的理解,Base類中的任何方法都可能被覆蓋,super可以被調用?那麼模板方法不僅僅是覆蓋基類中的方法嗎?Objective-C - 模板方法模式?
如果我錯了,你能解釋一下模板方法模式是什麼,你能提供一個例子嗎?
所以我一直在閱讀關於Objective-C的模板方法,我正試圖理解它們的特殊之處。根據我的理解,Base類中的任何方法都可能被覆蓋,super可以被調用?那麼模板方法不僅僅是覆蓋基類中的方法嗎?Objective-C - 模板方法模式?
如果我錯了,你能解釋一下模板方法模式是什麼,你能提供一個例子嗎?
是的,模板模式不僅僅是覆蓋基類中的方法。
當算法的輪廓被具體定義時,可以使用模板模式,但算法的步驟是抽象的。這意味着這些步驟可以以不同的方式實施。但是,算法的總體輪廓預計不會改變。
,我剛纔在飛行中創建了一個例子:
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找到。
這個問題特別要求Objective-C的實現,但你使用了類似Java的東西。你能提供一個好的Objective-C等價物嗎?據我所知,Objective-C中沒有抽象關鍵字或任何等價的概念。 –
-1,因爲在Objective-C上下文中沒有設置答案。 – matm
如果可以,我也是-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的東西。要獲得有關這種模式的總體思路,筆者建議如下:
而且還有噸教程/文章的網頁上。基本思想不是Obj-C依賴。
我以爲我應該提供更多Objective-C的具體答案。你可以閱讀關於可可在蘋果Cocoa Design Patterns pages中使用的模板方法。一個例子是drawRect:
模板方法。像其他模板方法一樣,您從不直接自己調用模板方法。它被setNeedsDisplay
調用。這點的目的是讓框架優化繪圖。如果你自己直接調用drawRect:
,那麼最終可能會多次不必要地重畫。
事實上,你應該嘗試使你想要在子類中覆蓋模板方法的每個方法。這樣可以減少在重寫時調用基類實現並使調試更簡單的問題。你可以在基類中放置一個斷點,而不是在子類中重載每個方法。
如果你聽說過一種設計模式,並認爲「沒有多大的意義」,你大多是正確的。其中許多是顯而易見的。 – morningstar