iOS 开发每天分享优质文章iOS开发笔记

iOS开发之设计模式 - 策略模式

2019-03-28  本文已影响339人  JoeyM

由《大话设计模式 - 策略模式》的OC和部分Swift的语言转义

策略模式

继上一篇《简单工厂模式》

Alt text

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语言)


@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];
    }
    
}

对比下,两种设计模式的异同。结合之后对调用者来说,少了什么? 除此之外还有什么好处?

两个结合之后, 发现在context中又有了难看的if else? 怎么样才能替换带这个“该死”的东西? 《反射》 了解下!《抽象工厂模式》 里面有讲解。 (文章可能迭代需要一定时间, 这个模式在后面慢慢讲到,留个坑~)

下一篇装饰模式

上一篇下一篇

猜你喜欢

热点阅读