Delegates

From Rosetta Code
Revision as of 21:20, 3 October 2007 by rosettacode>Nirs (Objective C)
Task
Delegates
You are encouraged to solve this task according to the task description, using any language you may know.

A delegate is a helper object used by another object. The delegator may delegate some operations to the delegate, and provide a default implementation when there is not delegate or the delegate does not implement the operation. This pattern is heavily used in Cocoa framework on Mac OS X

Objects responsibilities:

Delegator:

  • Keep an optional delegate instance.
  • Allow setting the delegate when creating the instance or later.
  • Delegate the methods "thing" and "other" to the delegate.
  • Provide default implementation if there is no delegate or the delegate does not implement one of the method.

Delegate:

  • Implement "thing".
  • May implement "other", but don't implement it for this example.

Objective-C

@interface Delegator : NSObject
{
    id delegate;
}
- (id)delegate;
- (void)setDelegate:(id)obj;
- (NSString *)operation;
@end

@implementation Delegator
- (id)delegate;
{
    return delegate;
}
- (void)setDelegate:(id)obj;
{
    delegate = obj; // Weak reference
}
- (NSString *)operation;
{
    if ([delegate respondsToSelector:@selector(thing)])
        return [delegate thing];
    return @"default implementation";
}
@end

// Any object may implement these
@interface NSObject (DelegatorDelegating)
- (NSString *)thing;
@end

@interface Delegate : NSObject
// Don't need to declare -thing because any NSObject has this method
@end

@implementation Delegate
- (NSString *)thing;
{
    return @"delegate implementation";
}
@end

// Example usage
// Memory management ignored for simplification
int main()
{
    // Without a delegate
    Delegator *a = [[Delegator alloc] init];
    assert([[a operation] isEqualToString:@"default implementation"]);

    // With a delegate
    Delegate *d = [[Delegate alloc] init];
    [a setDelegate:d];
    assert([isEqualToString:@"delegate implementation"]);

    return 0;
}

==[[Python]]==
[[Category:Python]]

<pre>
class Delegator:
    def __init__(self, delegate=None):
        self.delegate = delegate
    def thing(self):
         if hasattr(self.delegate, 'thing'):
             return self.delegate.thing()
         return 42
    def other(self):
         if hasattr(self.delegate, 'other'):
             return self.delegate.thing()
         return 5

class Delegate:
    def thing(self):
        return 37

if __name__ == '__main__':

    # No delegate
    a = Delegator()
    assert a.thing() == 42
    assert a.other() == 5

    # With delegate
    a.delegate = Delegate()
    assert a.thing() == 37
    assert a.other() == 5