Ho bisogno di sviluppare un modello di strategia in cui ho una classe principale con altre tre classi in cui ho bisogno di fare riferimento agli oggetti delle altre tre classi usando l'oggetto di classe principale. Per risolvere questo è il modello di strategia mi aiuterà? Se sì, per favore dammi la sintassi in Objective-C?Come creare un modello di strategia in Objective-C?
risposta
Ti consigliamo di guardare il meccanismo protocol di Objective-C. Ecco un semplice protocollo con un unico metodo richiesto:
@protocol Strategy <NSObject>
@required
- (void) execute;
@end
Poi si dichiara una classe che soddisfa quel protocollo:
@interface ConcreteStrategyA : NSObject <Strategy>
{
// ivars for A
}
@end
L'applicazione deve fornire il metodo -execute
(da quando è stato dichiarato come @required
):
@implementation ConcreteStrategyA
- (void) execute
{
NSLog(@"Called ConcreteStrategyA execute method");
}
@end
è possibile effettuare una simile ConcreteStrategyB
classe, ma io non ho intenzione di mostrare qui.
Infine, creare una classe di contesto con una proprietà che mantenga la strategia corrente.
@interface Context : NSObject
{
id<Strategy> strategy;
}
@property (assign) id<Strategy> strategy;
- (void) execute;
@end
Ecco l'implementazione. Il metodo che delega al metodo -execute
della strategia si chiama anche -execute, ma non deve essere.
@implementation Context
@synthesize strategy;
- (void) execute
{
[strategy execute];
}
@end
Ora farò alcuni casi e mettere loro di utilizzare:
uscitaConcreteStrategyA * 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 mostra che la strategia è stata cambiata con successo:
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
Nota che se il il protocollo non specifica @required
, il metodo è facoltativo. In questo caso, il contesto ha bisogno di controllare se la strategia implementa il metodo:
- (void) execute
{
if ([strategy respondsToSelector:@selector(execute)])
[strategy execute];
}
Questo è un modello di cacao comune denominato delegation. Per ulteriori informazioni sulla delega e altri modelli di progettazione in Cocoa, see this.
Thank u tanto per il rispondi, un dubbio su quale sia la parola chiave "setStrategy" qui rappresentata nelle istanze che hai creato. – Cathy
Il metodo '-setStrategy:' viene generato automaticamente dalla direttiva '@ synthesize'. Se la proprietà è dichiarata 'retain', si occupa di conservare/rilasciare (ma devi ancora rilasciarlo in' -dealloc'). Ma se la proprietà è dichiarata 'assign', fa un semplice assegnamento come riferimento debole, con l'assunto che l'istanza assegnata sia garantita e che sia gestita altrove. In tal caso non dovrebbe essere rilasciato. ... In effetti, cambierò la mia risposta a questa seconda forma. –
Grazie per la risposta.Il @protocol dovrebbe essere necessario dichiararlo in un file separato – Cathy
Ecco un esempio un po 'più concreto. Puoi mettere ogni elemento in un file separato. Ho messo tutto in un unico file per facilità di comprensione.
// 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;
}
Questo sembra essere un duplicato della tua domanda esistente: http://stackoverflow.com/questions/2229026 –
Sì, ma non ho detto nulla su modello di strategia nella precedente interrogazione – Cathy