2011-11-16 7 views
6

He estado leyendo acerca de los métodos de plantilla en Objective-C y estoy tratando de entender qué tiene de especial. Desde mi punto de vista, cualquier método en una clase base puede ser anulado y se puede llamar a super. Entonces, ¿un método de plantilla es algo más que anular un método en la clase base?Objective-C - ¿Patrón de métodos de plantilla?

Si me equivoco, ¿puede explicar qué es una plantilla-método-patrón, y puede dar un ejemplo?

+1

Si escuchas sobre un patrón de diseño y piensas: "No hay mucho para eso", tienes más razón. Muchos de ellos son obvios. – morningstar

Respuesta

21

Sí, el patrón de la plantilla es un poco más que simplemente anular un método en la clase base.

El patrón de plantilla se puede usar cuando se define concretamente un contorno de un algoritmo, sin embargo, los pasos del algoritmo se dejan abstractos. Eso significa que los pasos se pueden implementar de diferentes maneras. Pero no se espera que el esquema general del algoritmo cambie.

Un ejemplo que acabo creado sobre la marcha:

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

Básicamente, la forma en que se espera un día para correr hacia abajo se define concretamente en el ramo de Vida. Sin embargo, los detalles del proceso son atendidos por la subclase (es decir, GoodLife). La clase de GoodLife implementará los pasos de manera muy diferente a una posible clase de ToughLife.

Existen algunas variaciones de este patrón; por ejemplo, algunos de los pasos también se pueden definir de manera concreta. En el ejemplo, eatLunch() se puede definir concretamente en la clase Life; lo que significa que no se espera que las subclases cambien este comportamiento.

El patrón tiene mucho sentido si tiene un algoritmo relativamente complejo que podría implementarse de diferentes maneras.

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

de alguna manera se perdió la parte con Objective-C en mi respuesta. Aquí es cómo se vería en 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 no se han incorporado en el apoyo a las clases abstractas, así que trabajó alrededor de ella usando el método doesNotRecognizeSelector:. Se pueden encontrar muchos más detalles sobre las clases abstractas & Objective-C here.

+0

La pregunta específicamente solicita una implementación de Objective-C, sin embargo, usó lo que parece ser Java. ¿Puedes proporcionar un buen equivalente de Objective-C? Hasta donde sé, no hay una palabra clave abstracta, o ninguna noción equivalente, en Objective-C. –

+0

-1 ya que la respuesta no está establecida en el contexto Objective-C. – matm

+0

Si pudiera, yo también -1. –

1

Según mi entender, cualquier método en una clase base puede ser anulado y se puede llamar al súper? Entonces, ¿un método de plantilla es algo más que anular un método en la clase base?

Sí, esto es mucho más que anular un método de clase base. Los métodos de plantilla son una forma de implementar un algoritmo donde algunos pasos dependen de las subclases. Por ejemplo, considere un método en Base que tiene tres pasos principales, f1, f2 y f3. Cada paso contiene una serie de declaraciones. Aquí f1 y f3 son iguales en todas las subclases, pero f2 depende de la subclase. Entonces, ¿qué hacer aquí? Puede anular todo el método en las declaraciones de copia de subclase de f1 y f3, pero eso es un desperdicio. Por lo tanto, solo proporciona f2 en la subclase. Y de esta manera usted define el algoritmo (ejecute f1, luego ejecute f2, luego ejecute f3) en la clase base, pero proporcione anclas para las subclases (f2). Tenga en cuenta que el método de plantilla en la clase base es final, por lo que la subclase no puede cambiar el algoritmo, p. no puede cambiar el orden de f1, f2 y f3, ninguna de las subclases puede omitir los pasos f1, f3.

En resumen, el patrón de Métodos de plantilla no solo está anulando, es el uso de la herencia para manejar algunas situaciones específicas. Esto no es específico de Obj-C, y no puedo proporcionarle nada específico para Obj-C. Para tener una idea general acerca de este patrón, recomiendo lo siguiente:

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

y también hay toneladas de tutoriales/artículos en la web. La idea básica no es dependiente de Obj-C.

2

Pensé que debería dar una respuesta más específica de Objective-C. Puede leer sobre el método de plantilla como se usa en Cocoa en manzanas Cocoa Design Patterns pages. Un ejemplo de esto es el método de plantilla drawRect:. Al igual que otros métodos de plantilla, nunca llamas directamente a los métodos de plantilla. Se llama por setNeedsDisplay. El objetivo de esto es permitir que el marco optimice el dibujo. Si llamaste directamente al drawRect: podrías terminar haciendo redibujos innecesarios muchas veces.

De hecho, probablemente debería tratar de hacer que cada método que desee sobrescribir en una subclase sea un método de plantilla. Esto reduce el problema de saber si debe llamar a la implementación de la clase base cuando anula y facilita la depuración. Puede colocar un punto de interrupción en la clase base, en lugar de poner en práctica todos los métodos anulados en las subclases.

Cuestiones relacionadas