• 设计模式:策略模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)


    上一篇《观察者模式》                                                       下一篇《建造者模式

    简介:

    策略模式,它是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换。策略模式让算法的变化独立于使用算法的客户,降低了耦合,增加了系统的可维护性和可扩展性。

    策略模式的结构包括三种角色:
    1、策略(Strategy):策略是一个接口,该接口定义了算法标识。
    2、具体策略(ConcreteStrategy):具体策略是实现策略接口的类,具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。
    3、上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。

    策略模式的使用场景:
    1、针对同一类型问题的多种处理方式,但具体行为有差别时。
    2、需要安全地封装多种同一类型的操作时。
    3、出现同一抽象类有多个子类,而又需要使用 if-else 或者 switch-case 来选择具体子类时。
    4、当业务功能是客户程序的一个难以分割的成分时,增加新的业务算法或改变现有算法将十分困难。
    5、当不同的时候需要不同的算法,我们不想支持我们并不使用的业务算法时。
    6、当算法使用了客户不应该知道的数据时。
    7、当一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现时。

    总之,策略模式是一种非常实用的设计模式,可以用于封装各种类型的规则,并且可以在不同的时间应用不同的业务规则。

    策略模式的创建步骤:
    1、定义策略接口:首先需要定义一个策略接口,该接口中包含算法的方法。
    2、创建具体策略类:根据策略接口,创建实现具体算法的类。
    3、创建上下文类:上下文类负责维护和查询策略对象,并在具体策略类中注入策略对象。
    4、在上下文类中注入策略对象:通过构造函数或者setter方法,将策略对象注入到上下文类中。
    5、在客户端中创建上下文对象:在客户端中创建上下文对象,并将具体策略对象注入到上下文对象中。
    6、客户端调用上下文对象:客户端通过上下文对象调用具体策略对象的方法,实现算法的调用。

    以上是策略模式的基本创建步骤,具体实现方式可能会因语言和需求而有所不同。

    策略模式的优点,主要包括:
    1、提供了对“开闭原则”的完美支持,可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
    2、提供了管理相关的算法族的办法,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
    3、提供了可以替换继承关系的办法,使得系统更加灵活和可维护。
    4、使用策略模式可以避免使用多重条件转移语句,如 if...else 语句、switch...case 语句。
    5、可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的实现方式。

    策略模式的缺点,主要包括:
    1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这可能违反了“开闭原则”。
    2、策略模式会造成产生很多策略类,增加了系统的复杂性和维护成本。
    3、在实现上,策略模式需要使用继承和多态,这会增加代码的复杂性和实现的难度。
    4、在使用策略模式时,需要注意策略的正确性和稳定性,因为不同的策略可能会对系统的行为产生不同的影响。

    总之,策略模式虽然可以提高系统的灵活性和可维护性,但也存在一些缺点需要注意。在使用策略模式时,需要根据具体情况进行权衡和考虑。

    示例:

    一、C#策略模式

    以下是一个示例,展示了如何在C#中实现策略模式:

    1. //定义策略接口
    2. public interface Strategy  
    3. {  
    4.     void Execute();  
    5. }
    6. //创建具体策略类
    7. public class ConcreteStrategyA : Strategy  
    8. {  
    9.     public void Execute()  
    10.     {  
    11.         Console.WriteLine("执行策略A");  
    12.     }  
    13. }  
    14.   
    15. public class ConcreteStrategyB : Strategy  
    16. {  
    17.     public void Execute()  
    18.     {  
    19.         Console.WriteLine("执行策略B");  
    20.     }  
    21. }
    22. //创建上下文类
    23. public class Context  
    24. {  
    25.     private Strategy strategy;  
    26.   
    27.     public Context(Strategy strategy)  
    28.     {  
    29.         this.strategy = strategy;  
    30.     }  
    31.   
    32.     public void SetStrategy(Strategy strategy)  
    33.     {  
    34.         this.strategy = strategy;  
    35.     }  
    36.   
    37.     public void DoSomething()  
    38.     {  
    39.         strategy.Execute();  
    40.     }  
    41. }
    42. //在客户端中创建上下文对象并注入具体策略对象
    43. public class Client{
    44.     public void Test(){
    45.         Context context = new Context(new ConcreteStrategyA());  
    46.         context.DoSomething();  // 输出:执行策略A  
    47.         context.SetStrategy(new ConcreteStrategyB());  
    48.         context.DoSomething();  // 输出:执行策略B
    49.     }
    50. }

    二、java策略模式

    策略模式通常通过以下方式实现:

    1. //定义策略接口
    2. public interface Strategy {  
    3.     void execute();  
    4. }
    5. //创建具体策略类
    6. public class ConcreteStrategyA implements Strategy {  
    7.     @Override  
    8.     public void execute() {  
    9.         System.out.println("执行策略A");  
    10.     }  
    11. }  
    12.   
    13. public class ConcreteStrategyB implements Strategy {  
    14.     @Override  
    15.     public void execute() {  
    16.         System.out.println("执行策略B");  
    17.     }  
    18. }
    19. //创建上下文类
    20. public class Context {  
    21.     private Strategy strategy;  
    22.   
    23.     public Context(Strategy strategy) {  
    24.         this.strategy = strategy;  
    25.     }  
    26.   
    27.     public void setStrategy(Strategy strategy) {  
    28.         this.strategy = strategy;  
    29.     }  
    30.   
    31.     public void doSomething() {  
    32.         strategy.execute();  
    33.     }  
    34. }
    35. //在客户端中创建上下文对象并注入具体策略对象
    36. public class Main {  
    37.     public static void main(String[] args) {  
    38.         Context context = new Context(new ConcreteStrategyA());  
    39.         context.doSomething();  // 输出:执行策略A  
    40.         context.setStrategy(new ConcreteStrategyB());  
    41.         context.doSomething();  // 输出:执行策略B
    42.     }
    43. }

    三、javascript策略模式

    在JavaScript中,策略实现方式如下:

    1. //定义策略接口
    2. function Strategy(execute) {  
    3.     this.execute = execute;  
    4. }
    5. //创建具体策略类
    6. class ConcreteStrategyA extends Strategy {  
    7.     constructor() {  
    8.         super(this.execute);  
    9.     }  
    10.   
    11.     execute() {  
    12.         console.log('执行策略A');  
    13.     }  
    14. }  
    15.   
    16. class ConcreteStrategyB extends Strategy {  
    17.     constructor() {  
    18.         super(this.execute);  
    19.     }  
    20.   
    21.     execute() {  
    22.         console.log('执行策略B');  
    23.     }  
    24. }
    25. //创建上下文类
    26. class Context {  
    27.     constructor(strategy) {  
    28.         this.strategy = strategy;  
    29.     }  
    30.   
    31.     setStrategy(strategy) {  
    32.         this.strategy = strategy;  
    33.     }  
    34.   
    35.     doSomething() {  
    36.         this.strategy.execute();  
    37.     }  
    38. }
    39. //在客户端中创建上下文对象并注入具体策略对象
    40. const context = new Context(new ConcreteStrategyA());  
    41. context.doSomething();  // 输出:执行策略A  
    42. context.setStrategy(new ConcreteStrategyB());  
    43. context.doSomething();  // 输出:执行策略B

    四、C++策略模式

    以下是在C++中实现策略模式:

    1. //定义策略接口
    2. class Strategy {  
    3. public:  
    4.     virtual void execute() = 0;  
    5. };
    6. //创建具体策略类
    7. class ConcreteStrategyA : public Strategy {  
    8. public:  
    9.     void execute() override {  
    10.         cout << "执行策略A" << endl;  
    11.     }  
    12. };  
    13.   
    14. class ConcreteStrategyB : public Strategy {  
    15. public:  
    16.     void execute() override {  
    17.         cout << "执行策略B" << endl;  
    18.     }  
    19. };
    20. //创建上下文类
    21. class Context {  
    22. public:  
    23.     Context(Strategy* strategy) : strategy_(strategy) {}  
    24.     void setStrategy(Strategy* strategy) {  
    25.         strategy_ = strategy;  
    26.     }  
    27.     void doSomething() {  
    28.         strategy_->execute();  
    29.     }  
    30. private:  
    31.     Strategy* strategy_;  
    32. };
    33. //在客户端中创建上下文对象并注入具体策略对象
    34. int main() {  
    35.     Context context(new ConcreteStrategyA());  
    36.     context.doSomething();  // 输出:执行策略A  
    37.     context.setStrategy(new ConcreteStrategyB());  
    38.     context.doSomething();  // 输出:执行策略B  
    39.     delete context.strategy_;  
    40.     delete context;  
    41.     return 0;  
    42. }

    五、python策略模式

    以下是在python中实现策略模式:

    1. //定义策略接口
    2. from abc import ABC, abstractmethod  
    3.   
    4. class Strategy(ABC):  
    5.     @abstractmethod  
    6.     def execute(self):  
    7.         pass
    8.         
    9. //创建具体策略类
    10. class ConcreteStrategyA(Strategy):  
    11.     def execute(self):  
    12.         print("执行策略A")  
    13.   
    14. class ConcreteStrategyB(Strategy):  
    15.     def execute(self):  
    16.         print("执行策略B")
    17.         
    18. //创建上下文类
    19. class Context:  
    20.     def __init__(self, strategy):  
    21.         self.strategy = strategy  
    22.       
    23.     def set_strategy(self, strategy):  
    24.         self.strategy = strategy  
    25.       
    26.     def do_something(self):  
    27.         self.strategy.execute()
    28.         
    29. //在客户端中创建上下文对象并注入具体策略对象
    30. context = Context(ConcreteStrategyA())  
    31. context.do_something()  # 输出:执行策略A  
    32. context.set_strategy(ConcreteStrategyB())  
    33. context.do_something()  # 输出:执行策略B

    六、go策略模式

    以下是一个示例,展示了如何在go中实现策略模式:

    1. //定义策略接口
    2. type Strategy interface {  
    3.     Execute()  
    4. }
    5. //创建具体策略类
    6. type ConcreteStrategyA struct{}  
    7.   
    8. func (s *ConcreteStrategyA) Execute() {  
    9.     fmt.Println("执行策略A")  
    10. }  
    11.   
    12. type ConcreteStrategyB struct{}  
    13.   
    14. func (s *ConcreteStrategyB) Execute() {  
    15.     fmt.Println("执行策略B")  
    16. }
    17. //创建上下文类
    18. type Context struct {  
    19.     strategy Strategy  
    20. }  
    21.   
    22. func (c *Context) SetStrategy(strategy Strategy) {  
    23.     c.strategy = strategy  
    24. }  
    25.   
    26. func (c *Context) DoSomething() {  
    27.     c.strategy.Execute()  
    28. }
    29. //在客户端中创建上下文对象并注入具体策略对象
    30. func main() {  
    31.     context := &Context{}  
    32.     context.SetStrategy(&ConcreteStrategyA{})  
    33.     context.DoSomething()  // 输出:执行策略A  
    34.     context.SetStrategy(&ConcreteStrategyB{})  
    35.     context.DoSomething()  // 输出:执行策略B  
    36. }

    七、PHP策略模式

    以下是一个示例,展示了如何在PHP中实现策略模式:

    1. //定义策略接口
    2. interface Strategy {  
    3.     public function execute();  
    4. }
    5. //创建具体策略类
    6. class ConcreteStrategyA implements Strategy {  
    7.     public function execute() {  
    8.         echo "执行策略A";  
    9.     }  
    10. }  
    11.   
    12. class ConcreteStrategyB implements Strategy {  
    13.     public function execute() {  
    14.         echo "执行策略B";  
    15.     }  
    16. }
    17. //创建上下文类
    18. class Context {  
    19.     private $strategy;  
    20.       
    21.     public function __construct(Strategy $strategy) {  
    22.         $this->strategy = $strategy;  
    23.     }  
    24.       
    25.     public function setStrategy(Strategy $strategy) {  
    26.         $this->strategy = $strategy;  
    27.     }  
    28.       
    29.     public function doSomething() {  
    30.         $this->strategy->execute();  
    31.     }  
    32. }
    33. //在客户端中创建上下文对象并注入具体策略对象
    34. $context = new Context(new ConcreteStrategyA());  
    35. $context->doSomething();  // 输出:执行策略A  
    36. $context->setStrategy(new ConcreteStrategyB());  
    37. $context->doSomething();  // 输出:执行策略B

    通过以上步骤,我们实现了策略模式,使得算法可以独立于使用它的客户端,并且可以在不修改原有系统的基础上选择算法或行为。这种设计模式使得程序更加灵活和可维护。策略模式体现了开闭原则和里氏替换原则,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态地切换不同的策略实现以进行替换。

    《完结》

    上一篇《观察者模式》                                                       下一篇《建造者模式》

  • 相关阅读:
    数据库报1205-Lock wait timeout exceeded; try restarting transaction解决方案
    盈利背后,美团渴望第二曲线
    OMS 3.4.0 发布,打造更安全易用的数据迁移体验
    Unity入门06——Unity重要组件和API(3)
    51单片机学习:DS18B20温度传感器实验
    Springboot的自动装配原理和文件上传FastDFS
    玩转TypeScript之你真的了解this所指对象吗
    python自动解析301、302重定向链接
    Redis-Bitmap位图及其常用命令详解
    [附源码]java毕业设计“云味坊”购物网站
  • 原文地址:https://blog.csdn.net/yetyrain/article/details/133976395