策略模式 - 维基百科,自由的百科全书

策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中華民國交個人所得稅”就有不同的算稅方法。

策略模式:

  • 定义了一族算法(业务规则);
  • 封装了每个算法;
  • 这族的算法可互换代替(interchangeable)。

结构

[编辑]
Strategy Pattern in UML
Strategy pattern in LePUS3 (legend)

示例

[编辑]
#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