Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorator pattern in Objective-C

I was thinking of using the decorator pattern to extend the functionality of a UIKit class. The problem that I'm facing is that from examples I've seen in other languages the pattern forces me to duplicate the decorated object's interface. Here's how I would see the pattern implemented:

// Inheritance used for compile time check only
@interface UIScrollViewDecorator : UIScrollView
{
    UIScrollview *decoratedScrollView;
}

- (id)initWithScrollView:(UISCrollView*)scrollView;

@end

@implementation UIScrollViewDecorator

- (id)initWithScrollView:(UISCrollView*)scrollView
{
    self = [super init];
    if(self != nil)
    {
        decoratedScrollView = [scrollView retain];
        // maybe set up some custom controls on decoratedScrollView
    }
}

// all methods for UIScrollView need to be manually passed to the decorated object
//   -- this is the problem
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
{
    // use "overwritten methods" to mess with the input for the decorated scroll view
    // most of the time though I have no need to make any adjustments here; I still need
    // to pass all these messages through so that outside users can interact with me just
    // like with a real UIScrollView
    [decoratedScrollView scrollRectToVisible:rect animated:animated];
}

@end

So to summarize, the problem is the duplication of the decorated object's method, even when I don't need to alter anything there. Is there a simpler way to pass along those methods that I don't need to "overwrite"? Could I use something like a NSProxy for this?

EDIT: This has become mostly a theoretical problem for me since I realized the decorator pattern is not what I needed to solve my actual problem. However, since I may come to use it again in the future, I'm still very interested in your answers.

like image 780
Mihai Damian Avatar asked Feb 04 '23 00:02

Mihai Damian


1 Answers

Yes, it is possible to implement the Decorator pattern in Objective-C with an NSProxy. You would have to implement methodSignatureForSelector: and forwardInvocation: to forward messages to the decorated object.

But I don't think that this would be a good solution for what you try to do here; sending invocations is very costly and is not intended for such a purpose - there are certainly better ways to achieve what you want to do, e.g. with Categories (or maybe method swizzling).

like image 116
w-m Avatar answered Feb 12 '23 06:02

w-m