1

To use Strategy Pattern in Objective-C, I think it is mainly by selector.

To omit if...else, use Objective-C runtime, convert string matching to choose selector (Strategy).

Am my understanding right?

Here is demo: Strategy Pattern in ResponderChain Communication Pattern.

create a Router to use ResponderChain Communication

#import "UIResponder+Router.h"

@implementation UIResponder (Router)

- (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo
{
    [[self nextResponder] routerEventWithName:eventName userInfo:userInfo];
}

@end

event sender:

[self routerEventWithName:kBLGoodsDetailBottomBarEventTappedBuyButton userInfo:nil];

event receiver:

#pragma mark - event response
- (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo
{

    /*
        do things you want
    */
    // call the upper ,by ResponderChain
    // [super routerEventWithName:eventName userInfo:userInfo];
}

Here is the Strategy part:

when the event sources are many, use strategy to specify the concrete situation.

#pragma mark - event response
- (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo
{

    NSInvocation *invocation = self.eventStrategy[eventName];
    [invocation setArgument:&userInfo atIndex:2];
    [invocation invoke];

    // call the upper ,by ResponderChain
    // [super routerEventWithName:eventName userInfo:userInfo];
}

- (NSDictionary <NSString *, NSInvocation *> *)eventStrategy
{
    if (_eventStrategy == nil) {
        _eventStrategy = @{
                               kBLGoodsDetailTicketEvent:[self createInvocationWithSelector:@selector(ticketEvent:)],
                               kBLGoodsDetailPromotionEvent:[self createInvocationWithSelector:@selector(promotionEvent:)],
                               kBLGoodsDetailScoreEvent:[self createInvocationWithSelector:@selector(scoreEvent:)],
                               kBLGoodsDetailTargetAddressEvent:[self createInvocationWithSelector:@selector(targetAddressEvent:)],
                               kBLGoodsDetailServiceEvent:[self createInvocationWithSelector:@selector(serviceEvent:)],
                               kBLGoodsDetailSKUSelectionEvent:[self createInvocationWithSelector:@selector(skuSelectionEvent:)],
                               };
    }
    return _eventStrategy;
}
  • 1
    It's unclear what you are asking here. – Robert Harvey Jan 19 '18 at 15:50
  • Strategy Pattern is abstract, I am asking whether I got it in a specific platform. And I give some sample code. – dengApro Jan 19 '18 at 15:52
  • 2
    My reading of the Strategy Pattern is that you can have two or more different implementations for one interface, and that you can choose the implementation you want at runtime. Is that what you have achieved here? See thomashanning.com/the-strategy-pattern – Robert Harvey Jan 19 '18 at 16:01
  • 1
    NSInvocation is for cases with dynamic number and types of arguments; you don't need it if the methods called all have a fixed signature known at compile time -- you can use objc_msgSend directly. In fact, since here they are all methods that take one object parameter, you can call it using performSelector:withObject:. Just store the selector as a string in your dictionary, and call it with performSelector:withObject:. – user102008 Jan 20 '18 at 17:43
  • I got it. The strategy pattern depends not on a concrete implementation of an algorithm. @Robert Harvey – dengApro Jan 24 '18 at 5:42
1

If you have any newish Objective-c compiler, like any MacOS or Ios compiler, you get rid of the invocations and use closures aka blocks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.