美文网首页
策略模式(Strategy Pattern)

策略模式(Strategy Pattern)

作者: long弟弟 | 来源:发表于2022-09-17 00:09 被阅读0次

    策略模式

    意图:定义一系列的算法,把他们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

    策略模式.jpg

    角色和职责

    1. Strategy
      策略(算法)抽象,定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法
    2. ConcreteStrategy
      各种策略(算法)的具体实现,以Strategy接口实现某具体算法
    3. Context
    • 用一个ConcreteStrategy对象来配置
    • 维护一个对Strategy对象的引用
    • 可定义一个接口来让Strategy访问它的数据
      策略的外部封装类,或者说策略的容器类。根据不同的策略执行不同的行为。策略由外部环境决定

    代码示例

    #import <Foundation/Foundation.h>
    //面向协议编程
    @protocol Strategy <NSObject>
    - (void)encrypt;
    @end
    
    @interface AES : NSObject <Strategy>
    @end
    @implementation AES
    - (void)encrypt {
        NSLog(@"AES 对称加密");
    }
    @end
    
    @interface RSA : NSObject <Strategy>
    @end
    @implementation RSA
    - (void)encrypt {
        NSLog(@"RSA 非对称加密");
    }
    @end
    
    @interface Context : NSObject
    @property (nonatomic, strong) id<Strategy> strategy;
    @end
    @implementation Context
    - (void)encrypt {
        NSLog(@"RSA 非对称加密");
    }
    - (void)setStrategy:(id<Strategy>)strategy {
        _strategy = strategy;
    }
    - (void)operator {
        [_strategy encrypt];
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            id<Strategy> strategy = [[AES alloc] init];
            //id<Strategy> strategy = [[RSA alloc] init];
            Context *ct = [[Context alloc] init];
            ct.strategy = strategy;
            [ct operator];
        }
        return 0;
    }
    /*
    AES 对称加密
    RSA 非对称加密
    */
    

    用处

    准备一组算法,并将每一个算法封装起来,使得它们可以互换。
    客户端和算法的实现(策略)解耦合
    算法的变化,不会影响客户端

    优点

    1. 避免使用多重条件判断
    2. 扩展性良好
    3. 面向抽象类编程,算法可以自由切换

    缺点

    1. 客户必须了解不同的Strategy
      本模式有一个潜在的缺点,就是一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的试下问题。因此仅当这些不同的行为变体与客户相关的行为时,才需要使用Strategy模式。
    2. Strategy和Context之间的通信开销
      无论各个ConcreteStrategy实现的算法是简单还是复杂,它们都共享Strategy定义的接口。因此很可能某些ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的ConcreteStrategy可能不使用其中的任何信息!这就意味着又是Context会创建和初始化一些永远不会用到的参数。如果存在这样的问题,那么将需要再Strategy和Context之间进行紧密的耦合。
    3. 增加了对象的数目
      Strategy增加了一个应用中的对象的数目。

    题外话

    单纯地看设计思路或代码实现,有些模式确实相似,比如策略模式和工厂模式。实际上,设计模式之间的主要区别还是在于意图,也就是应用场景。
    策略模式包含策略的定义、创建和使用三部分,从代码结构上看,它非常像工厂模式。它们的区别在于,策略模式侧重“策略”或“算法”这个特定的应用场景,用来解决根据运行时状态从一组策略中选择不同策略的问题,而工厂模式侧重封装对象的创建过程,这里的对象没有任何业务场景的限定,那可以是策略,也就可以是其他东西。但从设计意图上来看,这两个模式完全是两回事儿。
    策略模式和命令模式也有细微的区别。策略模式是不同的策略具有相同的目的、不同的实现、互相之间可以替换。比如代码中提到的AESRSA都是为了实现加密。而在命令模式中,命令是Receiver的行为参数化,不同的命令具有不同的目的,对应不同的处理逻辑,并且相互之间不可替换。

    相关文章

      网友评论

          本文标题:策略模式(Strategy Pattern)

          本文链接:https://www.haomeiwen.com/subject/yjahnrtx.html