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;
}
5
  • 1
    It's unclear what you are asking here. Jan 19, 2018 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, 2018 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 Jan 19, 2018 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, 2018 at 17:43
  • I got it. The strategy pattern depends not on a concrete implementation of an algorithm. @Robert Harvey
    – dengApro
    Jan 24, 2018 at 5:42

1 Answer 1

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.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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