命令模式(C++版本和Objective-C)

 命令模式:
 将请求封装成对象,然后对对象进行参数化,这样可以做到请求,撤销操作;
 1、c++版本:遥控器控制空调
    1.1、空调充当接受者receiver;
    1.2、遥控器充当invoker;
    1.3、遥控器按下开,关,加大温度,降低温度充当具体的命令;
 我们使用遥控器以命令的形式控制空凋的各种状态;
 2、NSInvocation充当具体的命令,我们参数化根据NSInvocation提供的
 各个属性进行设置,在外部调用的时候,设置Target-action,Target即我们具体对象对应receiver,
 action对应我们的具体动作如selector,具体命令需要在NSInvocation对象中封装,具体应用在JS和Native
 调用中,可以根据不同的类,函数返回值,参数名称,参数个数不限制 


#import <Foundation/Foundation.h>
#import <iostream>
#import "NSInvocationTest.h"
// receiver
class AirConditioning{
public:
    void turnOn(){
        NSLog(@"AirConditioning turnOn");
    }
    
    void turnOff(){
        NSLog(@"AirConditioning turnOff");
    }
    
    void ChangeTemperature(int temperature){
        NSLog(@"AirConditioning ChangeTemperature:%d",temperature);
    }
};

class ICommand{
protected:
    AirConditioning* _air;
public:
    virtual void execute(){
        
    }
    
    virtual void execute(int temperature){
           
    }
    
    virtual ~ICommand(){
        std::cout<<"~ICommand() invoke"<<std::endl;
    }
};

class CommandTurnOn:public ICommand{
public:
    CommandTurnOn(AirConditioning* air){
        _air = air;
    }
    void execute() {
        if (_air) {
            _air -> turnOn();
        }
    }
};

class CommandTurnOff:public ICommand{
public:
    CommandTurnOff(AirConditioning* air){
        _air = air;
    }
    void execute() {
        if (_air) {
            _air -> turnOff();
        }
    }
};

class CommandChangeTemperature:public ICommand{
public:
   CommandChangeTemperature(AirConditioning* air){
        _air = air;
    }
    void execute(int temperature){
        if (_air) {
           _air -> ChangeTemperature(temperature);
        }
    }
};

// invoker
class RemoteController{
private:
    CommandTurnOn*               _commandTurnOn;
    CommandTurnOff*              _commandTurnOff;
    CommandChangeTemperature*    _commandChangeTemperature;
public:
    RemoteController(CommandTurnOn* on,CommandTurnOff* off,CommandChangeTemperature* temp){
        _commandTurnOn = on;
        _commandTurnOff = off;
        _commandChangeTemperature = temp;
    }
    
    void turnOn(){
        if (_commandTurnOn) {
            _commandTurnOn -> execute();
        }
    }
    
    void turnOff(){
        if (_commandTurnOff) {
            _commandTurnOff -> execute();
        }
    }
    
    void ChangeTemperature(int temperature){
        if (_commandChangeTemperature) {
           _commandChangeTemperature -> execute(temperature);
        }
    }
};

static id callSelector(NSString* className,NSString* selectorName,NSArray* parmeters){
    
    Class cls = NSClassFromString(className);
    id target = [[cls alloc] init];
    SEL selector = NSSelectorFromString(selectorName);
    NSMethodSignature* methodSignature = [target methodSignatureForSelector:selector];
    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
    [invocation setSelector:selector];
    [invocation setTarget:target];
    [parmeters enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [invocation setArgument:&obj atIndex:idx + 2];
    }];
    [invocation invoke];
    
    char returnType[255];
    strcpy(returnType,[methodSignature methodReturnType]);
    switch (returnType[0]) {
        case 'v':
            
            break;
        case 'i':
        {
            int returnInt;
            [invocation getReturnValue:&returnInt];
            return @(returnInt);
        }
        case 'f':
        {
            float returnfloat;
            [invocation getReturnValue:&returnfloat];
            return @(returnfloat);
        }
        case '@':
        {
            id returnId;
            [invocation getReturnValue:&returnId];
            return returnId;
        }
        case 'd':
        {
            double returnDouble;
            [invocation getReturnValue:&returnDouble];
            return @(returnDouble);
        }
        default:
            //todo
            break;
         
    }
    id ret;

    return ret;
}

// client
int main(int argc, const char * argv[]) {
    @autoreleasepool {
    //C++ 命令模式
    AirConditioning* air = new AirConditioning();
    CommandTurnOn* commandTurnOn = new CommandTurnOn(air);
    CommandTurnOff* commandTurnOff = new CommandTurnOff(air);
    CommandChangeTemperature* commandChangeTemperature = new CommandChangeTemperature(air);
    RemoteController* invoker = new RemoteController(commandTurnOn,commandTurnOff,commandChangeTemperature);
    invoker -> turnOn();
    invoker -> turnOff();
    invoker -> ChangeTemperature(26);
    invoker -> ChangeTemperature(20);

    //Objective-C 命令模式之NSInvocation
    callSelector(@"NSInvocationTestA",@"testA:b:c:d:e:f:g:",@[@"aaa",@"bbb",@"ccc",@"ddd",@"ggg",@"ffff",@"SGGG"]);
    id retObjInt = callSelector(@"NSInvocationTestB",@"testB:b:c:d:e:f:g:",@[@"aaa",@"bbb",@"ccc",@"ddd",@"ggg",@"ffff",@"SGGG"]);
    id retObjFloat = callSelector(@"NSInvocationTestC",@"testC:b:c:d:e:f:g:",@[@"aaa",@"bbb",@"ccc",@"ddd",@"ggg",@"ffff",@"SGGG"]);
    id retObjId  = callSelector(@"NSInvocationTestD",@"testD:b:c:d:e:f:g:",@[@"aaa",@"bbb",@"ccc",@"ddd",@"ggg",@"ffff",@"SGGG"]);
    id retObjDouble  = callSelector(@"NSInvocationTestE",@"testE:b:c:d:e:f:g:",@[@"aaa",@"bbb",@"ccc",@"ddd",@"ggg",@"ffff",@"SGGG"]);
    NSLog(@"%@,%@,%@,%@",retObjInt,retObjFloat,retObjId,retObjDouble);
        
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值