Strategy(策略模式)

定义:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

问题:写一个类SortArray,该类包含一个int 的NSArray数组(为了简化问题,不考虑int不是NSObject了),该类提供一个sort方法,利用简单的插入排序,对这个数组进行排序

#import <Foundation/Foundation.h>

@interface SortArray : NSObject

-(void) sort;

@end
#import "SortArray.h"

@implementation SortArray
{
    NSArray* array;
}

-(void) sort
{
    for (int i=0; i<array.count; i++)
        for (int j=i+1; j<array.count; j++)
        {
            if (array[i]>array[j])
            {
                swap(array[i],array[j]);
            }
        }
}

@end

一个很简单的SortArray类,我们几行代码搞定。

但是,新的问题出现了,某个客户因为需求,认为你的插入排序效率太低,需要你改用其他排序方法(比如 快排或者 堆)

这时候 我们遇到了一个问题,SortArray已经被封装过了 我们怎么可以去修改一个封装过了的代码?问题产生的原因在于 我们吧sort函数写死了,如果sort算法发生改变,我们不得不去修改原有的代码 这又违反了OCP原则

请注意这里和Template Method不一样的地方,这里 我们是需要修改整个算法,而Template Method只需要修改算法的一部分。

好了 我们去思考一个新的解决办法,为了保证OCP原则 我们将sort里面的代码分离出去(因为这个是变化的,也就是整个类会发生改变的地方),新建一个SortAlgorithm的抽象类,这个抽象类包含一个抽象方法 sortArray:(NSArray*)array,变成这样

#import <Foundation/Foundation.h>

@interface SortAlgorithm : NSObject

-(void) sortArray:(NSArray*)array;	//这个方法不需要实现,留给子类实现

@end
然后 我们新建一个叫做InsertSortAlgorithm的类,该类继承自SortAlgorithm,另外 把原来SortArray里面的排序算法代码放到InsertSortAlgorithm得sortArray函数中

#import "SortAlgorithm.h"

@interface InsertSortAlgorithm : SortAlgorithm

-(void) sortArray:(NSArray *)array;

@end
#import "InsertSortAlgorithm.h"

@implementation InsertSortAlgorithm

-(void) sortArray:(NSArray *)array
{
    for (int i=0; i<array.count; i++)
        for (int j=i+1; j<array.count; j++)
        {
            if (array[i]>array[j])
            {
                swap(array[i],array[j]);
            }
        }
}

@end
同时 在原来的SortArray类中添加一个SortAlgorithm变量,在sort函数中直接使用SortAlgorithm去调用对应的排序算法 变成这样

#import <Foundation/Foundation.h>
#import "SortAlgorithm.h"

@interface SortArray : NSObject

-(void) sort;

@property (nonatomic,strong) SortAlgorithm* sa;

@end
#import "SortArray.h"
#import "SortAlgorithm.h"

@implementation SortArray
{
    NSArray* array;
}

-(void) sort
{
    [self.sa sortArray:array];
}

@end
这样 外部在调用的时候 只需要设置好对应的SortAlgorithm即可,这就是Strategy.

这时候 当需求发生改变的时候,比如 我们需要快速排序时,只需要重新写一个类QuickSortAlgorithm继承自SortAlgorithm即可,无需再去修改原本的SortArray.又一次做到了对修改封闭的原则

用户在调用的时候也特别的简单,只需要 设置好对应的算法 像这样即可

    SortArray* obj=[[SortArray alloc] init];
    obj.sa=[[InserSortAlogtithm alloc] init];
    [obj sort];


这就是Strategy

回到定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。这里的一系列算法指的就是各种的排序算法,我们把排序算法和需要排序的对象分割开,让所有的算法封装起来,而SortArray在响应变动的时候并不需要发生改变,他被独立了出来。

每次我再学习一个新的设计模式的时候 总会再想这样做得好处,后来 渐渐的也发现 设计模式 其实不会减少你得代码量 甚至可能会加大你得代码量 但是 他的好处在于一个你已经封装好了得类不需要在去做出修改 因为当项目一旦庞大的时候 你得任何一个修改都可能导致未知的错误出现 这反而会增加你得开发成本,所以 设计模式不是说去减少你得代码量 让你的开发变得更方便,而应该是帮组你长期维护一个项目时 显得更容易

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值