策略模式
軟件設計模式
策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中華民國交個人所得稅”就有不同的算稅方法。
策略模式:
- 定义了一族算法(业务规则);
- 封装了每个算法;
- 这族的算法可互换代替(interchangeable)。
结构
示例
#include <iostream>
using namespace std;
class StrategyInterface
{
public:
virtual void execute() = 0;
};
class ConcreteStrategyA: public StrategyInterface
{
public:
virtual void execute()
{
cout << "Called ConcreteStrategyA execute method" << endl;
}
};
class ConcreteStrategyB: public StrategyInterface
{
public:
virtual void execute()
{
cout << "Called ConcreteStrategyB execute method" << endl;
}
};
class ConcreteStrategyC: public StrategyInterface
{
public:
virtual void execute()
{
cout << "Called ConcreteStrategyC execute method" << endl;
}
};
class Context
{
private:
StrategyInterface *_strategy;
public:
Context(StrategyInterface *strategy):_strategy(strategy)
{
}
void set_strategy(StrategyInterface *strategy)
{
_strategy = strategy;
}
void execute()
{
_strategy->execute();
}
};
int main(int argc, char *argv[])
{
ConcreteStrategyA concreteStrategyA;
ConcreteStrategyB concreteStrategyB;
ConcreteStrategyC concreteStrategyC;
Context contextA(&concreteStrategyA);
Context contextB(&concreteStrategyB);
Context contextC(&concreteStrategyC);
contextA.execute();
contextB.execute();
contextC.execute();
contextA.set_strategy(&concreteStrategyB);
contextA.execute();
contextA.set_strategy(&concreteStrategyC);
contextA.execute();
return 0;
}
//StrategyExample test application
class StrategyExample {
public static void main(String[] args) {
Context context;
// Three contexts following different strategies
context = new Context(new FirstStrategy());
context.execute();
context = new Context(new SecondStrategy());
context.execute();
context = new Context(new ThirdStrategy());
context.execute();
}
}
// The classes that implement a concrete strategy should implement this
// The context class uses this to call the concrete strategy
interface Strategy {
void execute();
}
// Implements the algorithm using the strategy interface
class FirstStrategy implements Strategy {
public void execute() {
System.out.println("Called FirstStrategy.execute()");
}
}
class SecondStrategy implements Strategy {
public void execute() {
System.out.println("Called SecondStrategy.execute()");
}
}
class ThirdStrategy implements Strategy {
public void execute() {
System.out.println("Called ThirdStrategy.execute()");
}
}
// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {
Strategy strategy;
// Constructor
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
this.strategy.execute();
}
}
using System;
namespace Wikipedia.Patterns.Strategy
{
// MainApp test application
class MainApp
{
static void Main()
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyA());
context.Execute();
context = new Context(new ConcreteStrategyB());
context.Execute();
context = new Context(new ConcreteStrategyC());
context.Execute();
}
}
// The classes that implement a concrete strategy should implement this
// The context class uses this to call the concrete strategy
interface IStrategy
{
void Execute();
}
// Implements the algorithm using the strategy interface
class ConcreteStrategyA : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
}
}
class ConcreteStrategyB : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
}
}
class ConcreteStrategyC : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyC.Execute()" );
}
}
// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context
{
IStrategy strategy;
// Constructor
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public void Execute()
{
strategy.Execute();
}
}
}
ActionScript 3
//invoked from application.initialize
private function init() : void
{
var context:Context;
context = new Context( new ConcreteStrategyA() );
context.execute();
context = new Context( new ConcreteStrategyB() );
context.execute();
context = new Context( new ConcreteStrategyC() );
context.execute();
}
package org.wikipedia.patterns.strategy
{
public interface IStrategy
{
function execute() : void ;
}
}
package org.wikipedia.patterns.strategy
{
public final class ConcreteStrategyA implements IStrategy
{
public function execute():void
{
trace( "ConcreteStrategyA.execute(); invoked" );
}
}
}
package org.wikipedia.patterns.strategy
{
public final class ConcreteStrategyB implements IStrategy
{
public function execute():void
{
trace( "ConcreteStrategyB.execute(); invoked" );
}
}
}
package org.wikipedia.patterns.strategy
{
public final class ConcreteStrategyC implements IStrategy
{
public function execute():void
{
trace( "ConcreteStrategyC.execute(); invoked" );
}
}
}
package org.wikipedia.patterns.strategy
{
public class Context
{
private var strategy:IStrategy;
public function Context(strategy:IStrategy)
{
this.strategy = strategy;
}
public function execute() : void
{
strategy.execute();
}
}
}
<?php
class StrategyExample {
public function __construct() {
$context = new Context(new ConcreteStrategyA());
$context->execute();
$context = new Context(new ConcreteStrategyB());
$context->execute();
$context = new Context(new ConcreteStrategyC());
$context->execute();
}
}
interface IStrategy {
public function execute();
}
class ConcreteStrategyA implements IStrategy {
public function execute() {
echo "Called ConcreteStrategyA execute method\n";
}
}
class ConcreteStrategyB implements IStrategy {
public function execute() {
echo "Called ConcreteStrategyB execute method\n";
}
}
class ConcreteStrategyC implements IStrategy {
public function execute() {
echo "Called ConcreteStrategyC execute method\n";
}
}
class Context {
var $strategy;
public function __construct(IStrategy $strategy) {
$this->strategy = $strategy;
}
public function execute() {
$this->strategy->execute();
}
}
new StrategyExample;
?>
@protocol Strategy <NSObject>
@required
- (void)print;
@end
@interface ConcreteStrategyA : NSObject<Strategy>
{
}
@end
@interface ConcreteStrategyB : NSObject<Strategy>
{
}
@end
@interface Context : NSObject
{
id<Strategy> _strategy;
}
@property (nonatomic, assign) id<Strategy> strategy;
-(void)doIt;
@end
@implementation ConcreteStrategyA
- (void)print
{
NSLog(@"Test01");
}
@end
@implementation ConcreteStrategyB
- (void)print
{
NSLog(@"Test02");
}
@end
@implementation Context
@synthesize strategy = _strategy;
-(void)doIt
{
[self.strategy print];
}
@end