objective-ctyphoon

Dependency injection vs singleton, Initialization


I'm working on a big project right now, and the app is taking advantage of many different services, as: Comments, likes, posts, purchase and so on..

I have a class for each service.

Now, I came to a point where I would like to restrict registered users only, for some actions, as post, comment, and so on..

Till now every class use to have only class methods, as the following:

 @interface UpdateOrderServies : NSObject

+(void)deleteOrder: (STOrder *)order
         andReturn: (void(^)(NSError *error))errorBlock;

+(void)updateOrder: (STOrder *)order
         andReturn: (void(^)(NSError *error))errorBlock;

But now, i would like to check first if the user is registerd, and if not, not to return a value. So the best way i figgerd out is changing the classes to singel tone, and asking every time the class is called, if the user is registerd like so:

+(id) getInstance {

    static UpdateOrderServies *__sharedDataModel = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __sharedDataModel = [[UpdateOrderServies alloc]init];

    });

    if (![__sharedDataModel userIsRegisterd]) {
        return nil;
    }

    return __sharedDataModel;

}

And it works, but, well, its not a very good answer as you can see.. i would like somthing more generic. I was thinking about using Typhoon dependency injection, but there is no place were i could check every call if the user is registered... Any idea for a better way to deal with this issue? more dynamic...


Solution

  • Based on your question above, I think you're not looking for dependency injection but Aspect Oriented Programming.

    Aspect Orientes Programming (AOP) is designed to solve exactly the kinds of problem you describe above - those that cut across many modules in your system. Examples:

    If we use normal Object Oriented programming for these cross-cutting requirements, we break the single responsibility principle and a class that should've been nearly about one topic is now taking on more roles which gets confusing, repetitive and messy.

    AOP modularizes these cross-cutting concerns and then identifies all of the places these should be applied using method interception. (In AOP we call this a point-cut expression).

    In Objective-c you could either do manual AOP using ISA-swizzling, message forwarding or or using NSProxy - these are all ways of achieving method interception at run-time. Alternatively, you could use a library and one such library called 'Aspects' by Pete Steinberger and team. This library doesn't have a point-cut expression language as yet, but is still certainly much simpler than using the ObjC run-time directly to intercept methods.

    Summary of how an Authorization Aspect would work:

    This way your cross-cutting requirement (authorizing client invocations) isn't repeated. Now you may to decide for the sake of simplicity that you can prefer with having each service call invoking an authorization module, but it nonetheless helps to know the theory behind AOP and cross-cutting concerns.

    Dependency Injection / Typhoon

    Dependency injection doesn't really relate directly to your question, though it can certainly help to avoid the pitfalls of your singleton clients: