object-c 策略模式


策略模式的定义,《HeadFirst》这本书,定的比较详细,此文不作过多描述。

对于策略模式,将从下面几个方面进行分析:

方面一:策略模式和适用的场景。

1.类中定义了很多条件判断语句来进行不同的选择。

2.不想把类中的具体细节,数据结构暴露给调用者。

这种说法好似放之四海而皆准,太过朦胧,有点雾里看花。下面使用一个常见的例子来说明。


以生活中面试为例:一个公司有不同的岗位(Cocos2d手游、Python 、ai工程师、设计),有A,B ,C,D

等应聘者前来面试不同的工作岗位。这个公司有个规定,需要应聘者做相应的笔试题目。

如果不用策略模式实现的话可能会写成这样:


  if  "Cocos2d手游":

       做 Cocos2d手游 题目

  else if "Python":

     做 python 题目:


这种情况 如果条件语句比较少的话,没什么问题 ,但是在更新的时候可能就比较烦了,需要扩展这个条件判断语句

即把自己的条件语句加到上面这段代码中。这对于代码设计而言对于结构不太友好,且对于过多的条件语句,难以维护。而策略模式,生就是为了解决这种问题的。


方面二:策略模式类的角色分析。

     角色一:抽象策略基类,这个类是用来封装规范接口的,对于策略执行者而言它是不知道具体的策略内容的。

     在整个模式中,担任2个角色:保持具体策略的引用,规范接口。

    

   角色二:具体的策略类,这个类需要扩展抽象策略基类,统一规范接口。方便使用基类引用时进行调用。

在上面的例子中可理解为:不同的岗位(Cocos2d手游、Python 、ai工程师、设计)对应的笔试题目。


   角色三:策略选择器,由谁来分发策略。上面的例子中,这个角色一般由HR来担任。很明显,HR需要知道策略(具体的策略内容可以不知道),然后根据不同的应聘者选择不同的笔试题目。



下面根据这三个角色来进行笔试题目分发:

 抽象基类:


#import <Foundation/Foundation.h>


/**
 策略基类,规范策略执行的接口,具体的策略由各自的策略对象去执行
 */
@interface StrategyBase : NSObject



/**
 执行策略
 */
-(void) executeStrategy;

@end

。m文件:

#import "StrategyBase.h"

@implementation StrategyBase

-(void) executeStrategy{
    
    NSLog(@"如果不定义具体的策略,我就执行默认的策略");

}
@end


具体的策略类:这里只用Cocos2d 与python为例:

Cocos2dStrategy.h:

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

@interface Cocos2dStrategy : StrategyBase


//重载基类的 执行策略接口,可以不必在头文件中进行声明,这样写只是为了规范

-(void) executeStrategy;

@end

.m文件:

#import "Cocos2dStrategy.h"

@implementation Cocos2dStrategy

-(void) executeStrategy{


    NSLog(@"cocos2d 岗位需要,选择这里的策略");
}

@end


同理python。h文件为:

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

@interface PythonStrategy : StrategyBase

-(void)executeStrategy;

@end



.m文件:

#import "PythonStrategy.h"

@implementation PythonStrategy

-(void) executeStrategy{
    
    NSLog(@"Python 岗位,选择这这里的策略");

}

@end


策略选择器,也即为HR扮演的角色:

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


/**
 策略选择器,负责选择具体的策略
 因为具体的策略,在客户端选择之前是未定的,所以需要用策略基类来保持具体的策略的引用
 */
@interface StrategySelecter : NSObject


/**
 策略引用保持者
 */
@property(nonatomic,retain) StrategyBase* strategy;


+(instancetype) getInstance;

/**
 选择策略

 @param strategy 具体的策略对象
 */
-(void) selectStrategy:(StrategyBase*) strategy;



/**
 执行策略  这个方法其实可以省略,为了方便阅读,与解偶合执行的动作放在这里
 */
-(void) executeStrategy;

@end


.m文件:



//
//  StrategySelecter.m
//  DesignPattern
//
//  Created by 刘小兵 on 2017/7/21.
//  Copyright © 2017年 刘小兵. All rights reserved.
//

#import "StrategySelecter.h"

static StrategySelecter* strategyInstance = nil;
@implementation StrategySelecter

+(instancetype) getInstance{

    @synchronized (self) {
        if(strategyInstance == nil){
        
            strategyInstance = [[StrategySelecter alloc] init];
        }
    }
    return strategyInstance;

}

-(void) selectStrategy:(StrategyBase*) strategy{

    self.strategy = strategy;
    
    //高手一般都能看出来,策略选择器中的那个基类策略引用保持者,只 是为了代码的扩展性,如果没有那个引用
    // [strategy executeStrategy ];

}

-(void) executeStrategy{
    
    if(self.strategy){
    
        [self.strategy executeStrategy];
    }

}

@end


测试方式:

StrategySelecter* selector = [StrategySelecter getInstance];
    
    Cocos2dStrategy* cocos2d = [[Cocos2dStrategy alloc] init];
    
    
    [selector selectStrategy:cocos2d];
    
    
    [selector selectStrategy:[[PythonStrategy alloc] init]];


测试结果:




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值