由《大话设计模式 - 策略模式》的OC和部分Swift的语言转义
策略模式
继上一篇《简单工厂模式》
- 策略模式,定义了算法家族,分别封装起来, 让他们之间可以相互替换, 此模式让算法的变化,不会影响到使用算法的客户。
OC
// 策略模式
#import "ViewController1.h"
// 抽象算法类
@interface Strategy : NSObject
- (void)AlgorithmInterface;
@end
@implementation Strategy
- (void)AlgorithmInterface{ }
@end
// 封装了集体的算法或行为,继承自Strategyy
@interface ConcreteStrategyyA : Strategy
@end
@implementation ConcreteStrategyyA
- (void)AlgorithmInterface
{
NSLog(@"算法A实现");
}
@end
// 封装了集体的算法或行为,继承自Strategy
@interface ConcreteStrategyyB : Strategy
@end
@implementation ConcreteStrategyyB
- (void)AlgorithmInterface
{
NSLog(@"算法B实现");
}
@end
// 封装了集体的算法或行为,继承自Strategyy
@interface ConcreteStrategyyC : Strategy
@end
@implementation ConcreteStrategyyC
- (void)AlgorithmInterface
{
NSLog(@"算法C实现");
}
@end
// Contex 用一个ConcreteStrategyy来配置, 维护一个对Strategyy对象的引用
@interface Context : NSObject
- (void)context:(Strategy *)strategy;
@end
@implementation Context
{
Strategy *priviteStrategy;
}
- (void)context:(Strategy *)strategy
{
// 初始化的时候, 传入一个策略对象
priviteStrategy = strategy;
[self contextInterface];
}
- (void)contextInterface {
// 根据具体的策略对象,调用其算法的方法
[priviteStrategy AlgorithmInterface];
}
@end
@interface ViewController1 ()
@end
@implementation ViewController1
- (void)viewDidLoad {
[super viewDidLoad];
Context *context = [[Context alloc] init];
ConcreteStrategyyA * a = [ConcreteStrategyyA new];
[context context:a];
ConcreteStrategyyB * b = [ConcreteStrategyyB new];
[context context:b];
}
@end
小型样例(摘自大话设计模式, 但我已经转成OC语言)
- 商场收银软件, 营业员根据客户所购买的商品的单价和属性,向客户收费。
- 商场随机打折, 85折,5折。满300减50等等, 活动不定时, 方式变化不一
@interface CashSuper : NSObject
- (double)acceptCash:(double)money;
@end
@implementation CashSuper
- (double)acceptCash:(double)money { return 0.0f; }
@end
// 正常价位
@interface CashNormal : CashSuper
@end
@implementation CashNormal
- (double)acceptCash:(double)money
{
NSLog(@"正常价位");
return money;
}
@end
// 打百分比折
@interface CashRebate : CashSuper
/**
手动输入打折率
@param moneyRebate 字符串
*/
- (void)cashRebate:(NSString *)moneyRebate;
@end
@implementation CashRebate
{
double priviteMoneyRebate;
}
- (void)cashRebate:(NSString *)moneyRebate {
priviteMoneyRebate = [moneyRebate doubleValue];
}
- (double)acceptCash:(double)money
{
NSLog(@"打百分比折");
return money * priviteMoneyRebate;
}
@end
// 满减收费子类
@interface CashReturn : CashSuper
/**
满减返利
@param moneyCondition 输入满减条件
@param moneyReturn 满减钱数
(比如 满300 减 50 moneyReturn = 300, moneyReturn = 50)
*/
- (void)cashReturn:(NSString *)moneyCondition moneyReturn:(NSString *)moneyReturn;
@end
@implementation CashReturn
{
double priviteMoneyConditon;
double priviteMoneyReturn;
}
- (void)cashReturn:(NSString *)moneyCondition moneyReturn:(NSString *)moneyReturn {
priviteMoneyConditon = [moneyCondition doubleValue];
priviteMoneyReturn = [moneyReturn doubleValue];
}
- (double)acceptCash:(double)money {
// 计算满减算法
NSLog(@"满减算法");
return 0.0;
}
@end
@interface CashContext : CashSuper
- (void)cashContext:(CashSuper *)cashSuper;
- (double)getResult:(double)money;
@end
@implementation CashContext
{
CashSuper *priviteCashSuper;
}
- (void)cashContext:(CashSuper *)cashSuper {
priviteCashSuper = cashSuper;
}
- (double)getResult:(double)money {
return [priviteCashSuper acceptCash:money];
}
@end
@interface ViewController1 ()
@end
@implementation ViewController1
- (void)viewDidLoad {
[super viewDidLoad];
CashContext *cs = [CashContext new];
// 此项目不展示label。请自行添加
if ([label.text isEqualToString:@"正常收费"]) {
[cs cashContext:[CashNormal new]];
[cs getResult:2];
} else if ([label.text isEqualToString:@"8折"]) {
[cs cashContext:[CashRebate new]];
[cs getResult:2];
} else {
[cs cashContext:[CashRebate new]];
[cs getResult:2];
}
}
实时上,开发过程中最常用的还是策略和简单工厂的结合(即为 中转站和工厂的双向结合)
- 修改商场促销
@interface CashContext : CashSuper
//- (void)cashContext:(CashSuper *)cashSuper; // 替换
- (void)cashContext:(NSString *)cashTypeString;
- (double)getResult:(double)money;
@end
@implementation CashContext
{
CashSuper *priviteCashSuper;
}
// 替换
//- (void)cashContext:(CashSuper *)cashSuper {
// priviteCashSuper = cashSuper;
//}
- (void)cashContext:(NSString *)cashTypeString {
if ([cashTypeString isEqualToString:@"正常"]) {
CashNormal *csN = [CashNormal new];
priviteCashSuper = csN;
} else if ([cashTypeString isEqualToString:@"满300减50"]) {
CashReturn *csRn = [CashReturn new];
priviteCashSuper = csRn;
} else { // 8折
CashRebate *csR = [CashRebate new];
priviteCashSuper = csR;
}
}
- (double)getResult:(double)money {
return [priviteCashSuper acceptCash:money];
}
@end
@implementation ViewController1
- (void)viewDidLoad {
[super viewDidLoad];
// CashContext *cs = [CashContext new];
// // 此项目不展示label。请自行添加
// if ([label.text isEqualToString:@"正常收费"]) {
// [cs cashContext:[CashNormal new]];
// [cs getResult:2];
// } else if ([label.text isEqualToString:@"8折"]) {
// [cs cashContext:[CashRebate new]];
// [cs getResult:2];
// } else {
// [cs cashContext:[CashRebate new]];
// [cs getResult:2];
// }
CashContext *cs = [CashContext new];
if ([label.text isEqualToString:@"正常收费"]) {
[cs getResult:2];
} else if ([label.text isEqualToString:@"8折"]) {
[cs getResult:2];
} else {
[cs getResult:2];
}
}