J'ai besoin de développer un modèle de stratégie dans lequel j'ai une classe principale avec trois autres classes où je dois faire référence aux objets des trois autres classes en utilisant l'objet de la classe principale. Si oui, veuillez me donner la syntaxe en Objective-C ?
Réponses
Trop de publicités?Vous voudrez bien consulter la page de l'Objective-C intitulée protocole mécanisme. Voici un protocole simple avec une seule méthode requise :
@protocol Strategy <NSObject>
@required
- (void) execute;
@end
Ensuite, vous déclarez une classe qui remplit ce protocole :
@interface ConcreteStrategyA : NSObject <Strategy>
{
// ivars for A
}
@end
La mise en œuvre doit fournir le -execute
(puisqu'elle a été déclarée comme @required
) :
@implementation ConcreteStrategyA
- (void) execute
{
NSLog(@"Called ConcreteStrategyA execute method");
}
@end
Vous pouvez faire une ConcreteStrategyB
mais je ne vais pas le montrer ici.
Enfin, créez une classe de contexte avec une propriété conservant la stratégie actuelle.
@interface Context : NSObject
{
id<Strategy> strategy;
}
@property (assign) id<Strategy> strategy;
- (void) execute;
@end
Voici la mise en œuvre. La méthode qui délègue à la stratégie -execute
s'appelle également -execute, mais ce n'est pas obligatoire.
@implementation Context
@synthesize strategy;
- (void) execute
{
[strategy execute];
}
@end
Je vais maintenant créer quelques instances et les utiliser :
ConcreteStrategyA * 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 console indique que la stratégie a été modifiée avec succès :
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
Notez que si le protocole ne spécifie pas de @required
La méthode est facultative. Dans ce cas, le contexte doit vérifier si la stratégie implémente la méthode :
- (void) execute
{
if ([strategy respondsToSelector:@selector(execute)])
[strategy execute];
}
Il s'agit d'un modèle commun à Cocoa appelé délégation . Pour plus d'informations sur la délégation et d'autres modèles de conception dans Cocoa, voir ceci .
Voici un exemple un peu plus concret. Vous pouvez placer chaque élément dans un fichier séparé. J'ai regroupé le tout dans un seul fichier pour faciliter la compréhension.
// 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;
}