今天,介绍一下策略模式。
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用类之间的耦合。
下面我把策略模式的类层次结构图展示如下:
如图所示,Strategy类层次为Context定义了一系列的可供重用的算法和行为,继承有助于析取出这些算法中的公共功能。下面我用一个普通超市里收费的例子简单模拟了这个模式。我把其中对应的类介绍一下:
-
Context类-------------------------CashContext类
-
Strategy类---------------------------CashSuper类
-
ConcreteStrategyA类-------------CashNormal类
-
ConcreteStrategyB类-------------CashRebate类
-
ConcreteStrategyC类-------------CashReturn类
好的,上面就是将要向大家展示的Objective C源代码类。
下面,我把上面对应的类展示出来,供大家参考:
-
CashContext类接口
1
2
3
4
5
6
7
8
9
10
|
#import <Foundation/Foundation.h>
#import "CashSuper.h"
@interface
CashContext:
NSObject
{
@private
CashSuper *cs;
}
-(CashContext*)MyInit:(
int
)Types;
-(
void
)SetCashSuper:(CashSuper*)cashSuper;
-(
double
)GetResult:(
double
)money;
@end
|
-
CashContext类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#import "CashContext.h"
#import "CashNormal.h"
#import "CashRebate.h"
#import "CashReturn.h"
@implementation
CashContext
-(CashContext*)MyInit:(
int
)Types{
int
myTypes;
myTypes = Types;
switch
(myTypes) {
case1:
[
self
SetCashSuper:[[CashNormalalloc]init]];
break
;
case2:
[
self
SetCashSuper:
[[CashReturnalloc]MyInit:300 And:100]];
break
;
case3:
[
self
SetCashSuper:[[CashRebatealloc]MyInit:0.8]];
break
;
default
:
break
;
}
return
self
;
}
-(
void
)SetCashSuper:(CashSuper*)cashSuper{
cs = cashSuper;
}
-(
double
)GetResult:(
double
)money{
return
[cs AcceptCash:money];
}
@end
|
-
CashSuper类接口
1
2
3
4
5
|
#import <Foundation/Foundation.h>
@interface
CashSuper:
NSObject
-(
double
)AcceptCash:(
double
)money;
@end
|
-
CashSuper类实现
1
2
3
4
5
6
7
8
9
|
#import"CashSuper.h"
@implementation
CashSuper
-(
double
)AcceptCash:(
double
)money{
return
-1.0;
//这里返回 -1.0无任何意义,只是为了定义此方法
}
@end
|
-
CashNormal类接口
1
2
3
4
5
|
#import"CashSuper.h"
@interface
CashNormal :CashSuper
@end
|
-
CashNormal类实现
1
2
3
4
5
6
7
8
9
|
#import"CashNormal.h"
@implementation
CashNormal
-(
double
)AcceptCash:(
double
)money{
return
money;
}
@end
|
-
CashRebate类接口
1
2
3
4
5
6
7
8
|
#import"CashSuper.h"
@interface
CashRebate:CashSuper{
@private
double
moneyRebate;
}
@property
double
moneyRebate;
-(CashRebate*)MyInit:(
double
)moneyRebates;
@end
|
-
CashRebate类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#import"CashRebate.h"
@implementation
CashRebate
@synthesize
moneyRebate;
-(CashRebate*)MyInit:(
double
)moneyRebates{
[
self
setMoneyRebate:moneyRebates];
return
self
;
}
-(
double
)AcceptCash:(
double
)money{
return
moneyRebate*money;
}
@end
|
-
CashReturn类接口
1
2
3
4
5
6
7
8
9
10
|
#import "CashSuper.h"
@interface
CashReturn:CashSuper{
@private
double
moneyCondition;
@private
double
moneyReturn;
}
@property
double
moneyCondition;
@property
double
moneyReturn;
-(CashReturn*)MyInit:(
double
)moneyConditions And:(
double
)moneyReturns;
@end
|
-
CashReturn类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#import "CashReturn.h"
@implementation
CashReturn
@synthesize
moneyReturn;
@synthesize
moneyCondition;
-(CashReturn*)MyInit:(
double
)moneyConditions And:(
double
)moneyReturns{
[
self
setMoneyReturn:moneyReturns];
[
self
setMoneyCondition:moneyConditions];
return
self
;
}
-(
double
)AcceptCash:(
double
)money{
double
result;
result = money;
@try
{
if
(money >=moneyCondition){
result = money - (money /moneyCondition)*moneyReturn;
}
}
@catch
(
NSException
*exception) {
NSLog
(@
"Oh!Man!!CashReturn has something wrong!"
);
}
@finally
{
return
result;
}
}
@end
|
-
Main方法调用
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#import <Foundation/Foundation.h>
#import "CashContext.h"
int
main (
int
argc,
const
char
*argv[])
{
@autoreleasepool
{
CashContext *cc = [[CashContext alloc]MyInit:3];
double
total;
total = [cc GetResult:400];
NSLog
(@
"Total Money 400,the resual is %f"
, total);
}
return
0;
}
|
以上是对应的策略模式中相应的类,有一点需要声明的是,这些代码是在有ARC环境下书写的,所以不需要手动释放其中的资源。所以有些传递指针地方没有进行手动释放,在此解释一下。
什么情况下需要用策略模式呢,其实我的理解是,当我们在分析需求的过程中,需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。另外,策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。