Necesito desarrollar un patrón de estrategia donde tengo una clase principal con otras tres clases donde necesito referirme a los objetos de las otras tres clases usando el objeto de clase principal. Para resolver esto, ¿me ayudará el patrón de estrategia? Si es así, ¿me das la sintaxis en Objective-C?¿Cómo crear un patrón de estrategia en Objective-C?
Respuesta
Tendrá que mirar el mecanismo protocol de Objective-C. Aquí hay un protocolo simple con un solo método requerido:
@protocol Strategy <NSObject>
@required
- (void) execute;
@end
A continuación, se declara una clase que cumple con ese protocolo:
@interface ConcreteStrategyA : NSObject <Strategy>
{
// ivars for A
}
@end
La aplicación debe proporcionar el método -execute
(desde que fue declarada como @required
):
@implementation ConcreteStrategyA
- (void) execute
{
NSLog(@"Called ConcreteStrategyA execute method");
}
@end
Usted puede hacer una clase similar ConcreteStrategyB
, pero no voy a mostrar aquí.
Finalmente, haga una clase de contexto con una propiedad que mantenga la estrategia actual.
@interface Context : NSObject
{
id<Strategy> strategy;
}
@property (assign) id<Strategy> strategy;
- (void) execute;
@end
Aquí está la implementación. El método que delega en el método -execute
de la estrategia simplemente se llama también -execute, pero no tiene que ser así.
@implementation Context
@synthesize strategy;
- (void) execute
{
[strategy execute];
}
@end
Ahora voy a hacer unos pocos casos y ponerlos en uso:
salidaConcreteStrategyA * concreteStrategyA = [[[ConcreteStrategyA alloc] init] autorelease];
ConcreteStrategyB * concreteStrategyB = [[[ConcreteStrategyB alloc] init] autorelease];
Context * context = [[[Context alloc] init] autorelease];
[context setStrategy:concreteStrategyA];
[context execute];
[context setStrategy:concreteStrategyB];
[context execute];
La consola muestra que la estrategia se cambió correctamente:
2010-02-09 19:32:56.582 Strategy[375:a0f] Called ConcreteStrategyA execute method
2010-02-09 19:32:56.584 Strategy[375:a0f] Called ConcreteStrategyB execute method
Tenga en cuenta que si el El protocolo no especifica @required
, el método es opcional. En este caso, el contexto tiene que comprobar si la estrategia implementa el método:
- (void) execute
{
if ([strategy respondsToSelector:@selector(execute)])
[strategy execute];
}
Este es un patrón común que se llama cacao delegation. Para obtener más información sobre la delegación y otros patrones de diseño en Cocoa, see this.
Gracias u tanto para el respuesta, una duda, ¿qué es la palabra clave 'setStrategy' aquí representa en las instancias que ha realizado. – Cathy
El método '-setStrategy:' se genera automáticamente con la directiva '@ sintetizar'. Si la propiedad se declara 'retener', se encarga de retener/liberar (pero aún tiene que liberarlo en' -dealloc'). Pero si la propiedad se declara 'assign', realiza una asignación simple como una referencia débil, con la suposición de que la instancia asignada se garantiza que existe y se administrará en otro lugar. En ese caso, no debería ser lanzado. ... De hecho, voy a cambiar mi respuesta a esta segunda forma. –
Gracias por la respuesta.El @protocol debería necesitar declararlo en el archivo separado – Cathy
Aquí hay un poco más de un ejemplo concreto. Puede poner cada elemento en un archivo separado. Lo puse todo en un solo archivo para facilitar la comprensión.
// main.m
// StrategyWikipediaExample
//
// Created by steve on 2014-07-08.
// Copyright (c) 2014 steve. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
Equivalent to Java Interface
All concrete Strategies conform to this protocol
*/
@protocol MathOperationsStrategy<NSObject>
- (void)performAlgorithmWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second;
@end
/**
Concrete Strategies.
Java would say they "Extend" the interface.
*/
@interface AddStrategy : NSObject<MathOperationsStrategy>
@end
@implementation AddStrategy
- (void)performAlgorithmWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second
{
NSInteger result = first + second;
NSLog(@"Adding firstNumber: %ld with secondNumber: %ld yields : %ld", first, second, result);
}
@end
@interface SubtractStrategy : NSObject<MathOperationsStrategy>
@end
@implementation SubtractStrategy
- (void)performAlgorithmWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second
{
NSInteger result = first - second;
NSLog(@"Subtracting firstNumer: %ld with secondNumber: %ld yields: %ld", first, second, result);
}
@end
@interface MultiplyStrategy : NSObject<MathOperationsStrategy>
@end
@implementation MultiplyStrategy
- (void)performAlgorithmWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second
{
NSInteger result = first * second;
NSLog(@"Multiplying firstNumber: %ld with secondNumber: %ld yields: %ld", first, second, result);
}
@end
@interface Context : NSObject
@property (weak, nonatomic)id<MathOperationsStrategy>strategy; // reference to concrete strategy via protocol
- (id)initWithMathOperationStrategy:(id<MathOperationsStrategy>)strategy; // setter
- (void)executeWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second;
@end
@implementation Context
- (id)initWithMathOperationStrategy:(id<MathOperationsStrategy>)strategy
{
if (self = [super init]) {
_strategy = strategy;
}
return self;
}
- (void)executeWithFirstNumber:(NSInteger)first secondNumber:(NSInteger)second
{
[self.strategy performAlgorithmWithFirstNumber:first secondNumber:second];
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
id<MathOperationsStrategy>addStrategy = [AddStrategy new];
Context *contextWithAdd = [[Context alloc] initWithMathOperationStrategy:addStrategy];
[contextWithAdd executeWithFirstNumber:10 secondNumber:10];
}
return 0;
}
- 1. Patrón de estrategia en Symfony2
- 2. Patrón de estrategia parametrizado
- 3. ¿Por qué el patrón de estrategia se llama patrón de estrategia?
- 4. ¿Patrón de estrategia sin declaraciones de "cambio"?
- 5. ¿Debería el patrón de estrategia ser apátrida?
- 6. Uso de un patrón de estrategia y un patrón de comando
- 7. Emailer en Java con el Patrón de estrategia
- 8. ¿Cómo usar el patrón de estrategia con C#?
- 9. Android: cómo crear un fondo del patrón?
- 10. Patrón de estrategia e inyección de dependencia usando Unity
- 11. ¿Mejor alternativa al patrón de estrategia en Scala?
- 12. Patrón de estrategia con diferentes parámetros en la interfaz (C#)
- 13. Variando los parámetros en el patrón de estrategia
- 14. Patrón de estrategia y explosión de clases de "acción"
- 15. Patrón de diseño de estrategia con contenedores IOC - Ninject específicamente
- 16. Patrón de estrategia frente a inyección de dependencia
- 17. ¿Cómo implementar un puente sin cargo en ObjectiveC/C?
- 18. Modificar if-else para el patrón de estrategia
- 19. Evitando el acoplamiento con el patrón de estrategia
- 20. ¿Cómo crear automáticamente un patrón basado en datos reales?
- 21. C# Patrón de diseño de estrategia por delegado vs OOP
- 22. Bloques ObjectiveC equivalente en Java
- 23. ¿Puedo colocar un ObjectiveC @selector en un NSDictionary?
- 24. ¿Es este un decorador o un patrón de estrategia, o ninguno de los dos?
- 25. Diferencia entre el patrón de estrategia y el patrón de delegación
- 26. Crear una burbuja/círculo de color programáticamente en ObjectiveC y Cocoa
- 27. Cómo dividir la nueva línea de NSString en ObjectiveC
- 28. Primavera: uso de patrón de generador para crear un bean
- 29. objectivec: fb publicar comentario error
- 30. ObjectiveC Parse Integer from String
Esto parece ser un duplicado de su pregunta existente: http://stackoverflow.com/questions/2229026 –
Sí, pero no he mencionado nada acerca patrón de estrategia en mi pregunta anterior – Cathy