12 votes

Comment créer un modèle de stratégie en Objective-C ?

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 ?

39voto

Jon Reid Points 9726

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 .

1voto

cocoanut Points 2396

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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X