我们先来看一下策略模式的定义:
1.它是行为模式的一种,对一系列的算法加以封装,为所有的算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定。策略模式是从n中算法选择一种算法来执行。
2.有点:提高了可以替换继承关系的方法,可以避免多重条件语句的判断
3.缺点:客户端必须知道所有的策略,这样才能知道选择哪种策略;每种算法都需要一个策略类,造成需要生成很多类
4.策略类的结构如下图:
Strategy:抽象的策略接口,iOS可以定义一个基类或者协议来实现
ConcreteStrategyA:具体的策略类,来实现具体的算法,继承Strategy
Contex:一个包含策略类的类,所以此类具有不同的具体策略类,来调用不同的策略算法
我们还是以上次装饰模式的例子来讲,假如火锅店举行周年庆,当天的菜8折,超过3天的9折,我们先不管菜的数量和种类,加入每桌点一份八折或者一份9折的菜,UML图如下所示:
代码如下:
1.DiscountStrategy:使用协议实现
@protocol DiscountStrategyProtocol
- (double)getDiscountPrice;
@end
2.EightDiscountStrategy:
@interfaceEightDiscountStrategy :NSObject
- (instancetype)initWithOriginalPrice:(double)price;
@end
#import "EightDiscountStrategy.h"
@interface EightDiscountStrategy()
@property (nonatomic,assign) double originalPrice;
@end
@implementation EightDiscountStrategy
- (instancetype)initWithOriginalPrice:(double)price
{
self= [superinit];
if(self) {
_originalPrice= price;
}
return self;
}
- (double)getDiscountPrice
{
return 0.8*_originalPrice;
}
3.NineDiscountStrategy同EightDiscountStrategy,不过是打9折
4.Contex:
@interface Contex : NSObject
- (instancetype)initWithStrategy:(id)strategy;
- (double)calculateDiscount;
@end
#import "Contex.h"
@interface Contex()
@property (nonatomic, weak) id
@end
@implementation Contex
- (instancetype)initWithStrategy:(id)strategy
{
self= [superinit];
if(self) {
_strategy= strategy;
}
return self;
}
- (double)calculateDiscount
{
return [self.strategy getDiscountPrice];
}
5.调用:
id
Contex*contex = [[Contexalloc] initWithStrategy:eightDiscountStategy];
[contex calculateDiscount];
id
Contex*contex = [[Contexalloc] initWithStrategy:nineDiscountStategy];
[contex calculateDiscount];
下面我们结合上次的装饰模式来看一下UML图,不限制顾客点菜的数量和种类:
装饰类、被装饰类、策略类都遵守相同的协议,装饰类的抽象类HuoGuoDecorator里面包含被装饰类huoGuoObj和具体的策略类strategyObj的实例对象,由于具体的装饰类继承于HuoGuoDecorator,所以具体的装饰类也包含被装饰类huoGuoObj和具体的策略类strategyObj的实例对象,由具体的策略类产生不同的打折算法,然后左边的装饰类动态组合右边产生的打折算法,然后去装饰被装饰者。上面是我的理解画的UML图,后两个豆腐的类可以换成别的不同类,代码我换成了niurou和tudou两个菜类,有啥不对的地方请大家指正。具体代码见:https://github.com/steven2008/DesignPattens.git,