2011-11-16 15 views
6

Quindi ho letto dei metodi di template su Objective-C e sto cercando di capire cosa c'è di speciale in loro. Dalla mia comprensione qualsiasi metodo in una classe Base può essere sorpassato e Super può essere chiamato? Quindi, un metodo di template è qualcosa di più che sovrascrivere un metodo nella classe base?Objective-C - Modello di metodi modello?

Se ho torto, puoi spiegare che cos'è un modello di modello di modello e puoi fornire un esempio?

+1

Se si sente parlare di uno schema di progettazione e si pensa "Non c'è molto da fare", hai quasi ragione. Molti di loro sono ovvi. – morningstar

risposta

21

Sì, lo schema modello è un po 'più di un semplice override di un metodo nella classe base.

Il modello di modello può essere utilizzato quando viene definito concretamente un profilo di un algoritmo, tuttavia i passaggi dell'algoritmo vengono lasciati astratti. Ciò significa che i passaggi possono essere implementati in diversi modi. Ma non ci si aspetta che lo schema generale dell'algoritmo cambi.

Un esempio che ho appena creato al volo:

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(); 

In sostanza, il modo in cui un giorno si prevede di correre giù è concretamente definite nella classe Vita. Tuttavia, i dettagli del processo sono curati dalla sottoclasse (ad esempio GoodLife). La classe GoodLife implementerà passaggi molto diversi rispetto a una possibile classe di ToughLife.

Ci sono alcune variazioni a questo modello; per esempio alcuni dei passaggi possono anche essere definiti concretamente. Nell'esempio, il eatLunch() può essere definito concretamente nella classe Life; il che significa che le sottoclassi non dovrebbero cambiare questo comportamento.

Il modello ha molto senso se si dispone di un algoritmo relativamente complesso che potrebbe essere implementato in modi diversi.

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

io in qualche modo ho perso la parte con Objective-C nella mia risposta. Ecco come dovrebbe apparire in 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 non dispone di un supporto incorporato per le classi astratte, così ho lavorato intorno ad esso utilizzando il metodo doesNotRecognizeSelector:. Ulteriori dettagli sulle classi astratte & L'obiettivo-C può essere trovato here.

+0

La domanda richiede specificamente un'implementazione Objective-C, ma hai usato quello che assomiglia a Java. Potete fornire un buon equivalente Objective-C? Per quanto ne so, non esiste una parola chiave astratta o una nozione equivalente in Objective-C. –

+0

-1 poiché la risposta non è impostata nel contesto Objective-C. – matm

+0

Se potesse, anche io -1. –

1

Dalla mia comprensione qualsiasi metodo in una classe Base può essere sorpassato e super può essere chiamato? Quindi, un metodo di template è qualcosa di più che sovrascrivere un metodo nella classe base?

Sì, questo è molto più di un semplice override di un metodo di classe base. I metodi di template sono un modo per implementare un algoritmo in cui alcuni passaggi dipendono dalla sottoclasse. Ad esempio, considera un metodo in Base che ha tre passaggi principali, f1, f2 e f3. Ogni passaggio contiene un numero di istruzioni. Qui f1 e f3 sono uguali in tutte le sottoclassi, ma f2 è dipendente dalla sottoclasse. Quindi cosa fare qui? Puoi sovrascrivere l'intero metodo nelle istruzioni di copia di sottoclasse di f1 e f3, ma questo è uno spreco. Quindi fornisci solo f2 in sottoclasse. E in questo modo definisci l'algoritmo (esegui f1, quindi esegui f2, quindi esegui f3) nella classe base, ma fornisci i hook di override per le sottoclassi (f2). Nota che il metodo template nella classe base è definitivo, quindi la sottoclasse non può cambiare l'algoritmo, ad es. non può cambiare l'ordine di f1, f2 e f3, nessuna sottoclasse può omettere i passi f1, f3.

In breve, il modello Metodi modello non è solo sovrascritto, è l'uso dell'ereditarietà per gestire alcune situazioni specifiche. Questo non è Obj-C specifico, e non posso fornirti nulla di specifico su Obj-C. Per avere un'idea complessiva su questo modello, vi consiglio i seguenti:

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

e ci sono anche un sacco di tutorial/articoli sul web. L'idea di base non è dipendente da Obj-C.

2

Ho pensato di dare una risposta più obiettiva all'obiettivo C. Puoi leggere il metodo del modello utilizzato in Cocoa sulle mele Cocoa Design Patterns pages. Un esempio di questo è il metodo del modello drawRect:. Come altri metodi di template, non si chiamano direttamente metodi di template. È chiamato da setNeedsDisplay. Il punto è di consentire al framework di ottimizzare il disegno. Se hai chiamato direttamente drawRect: potresti finire per non ripetere più volte i ridisegni.

In effetti dovresti probabilmente provare a rendere ogni metodo che desideri sovrascrivere in una sottoclasse un metodo di template. Ciò riduce il problema di sapere se è necessario chiamare l'implementazione della classe base quando si esegue l'override e si semplifica il debug. Puoi semplicemente inserire un breakpoint nella classe base, invece di tutti i metodi sovrascritti nelle sottoclassi.

Problemi correlati