Delegates: Difference between revisions
Content added Content deleted
(Typos) |
No edit summary |
||
Line 79: | Line 79: | ||
return 0; |
return 0; |
||
} |
} |
||
</pre> |
|||
==[[Pop11]]== |
|||
[[Category:Pop11]] |
|||
<pre> |
|||
uses objectclass; |
|||
define :class Delegator; |
|||
slot delegate = false; |
|||
enddefine; |
|||
define :class Delegate; |
|||
enddefine; |
|||
define :method thing(x : Delegate); |
|||
'delegate implementation' |
|||
enddefine; |
|||
define :method operation(x : Delegator); |
|||
if delegate(x) and fail_safe(delegate(x), thing) then |
|||
;;; Return value is on the stack |
|||
else |
|||
'default implementation' |
|||
endif; |
|||
enddefine; |
|||
;;; Default, without a delegate |
|||
lvars a = newDelegator(); |
|||
operation(a) => |
|||
;;; a delegating to itself (works because Delegator does not |
|||
;;; implement thing) |
|||
a -> delegate(a); |
|||
operation(a) => |
|||
;;; delegating to a freshly created Delegate |
|||
newDelegate() -> delegate(a); |
|||
operation(a) => |
|||
</pre> |
</pre> |
||
Revision as of 19:34, 20 October 2007
Delegates
You are encouraged to solve this task according to the task description, using any language you may know.
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 send the delegate certain messages, and provide a default implementation when there is no delegate or the delegate does not respond to a message. This pattern is heavily used in Cocoa framework on Mac OS X
Objects responsibilities:
Delegator:
- Keep an optional delegate instance.
- Implement "operation" method, returning the delegate "thing" if the delegate respond to "thing", or the string "default implementation".
Delegate:
- Implement "thing" and return the string "delegate implementaion"
Show how objets are created and used. First, without a delegate, then with a delegate that does not implement "thing", and last with a delegate that implements "thing".
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 that does not implement thing: [a setDelegate:@"A delegate may be any object"]; assert([isEqualToString:@"delegate implementation"]); // With a delegate that implements "thing": Delegate *d = [[Delegate alloc] init]; [a setDelegate:d]; assert([isEqualToString:@"delegate implementation"]); return 0; }
Pop11
uses objectclass; define :class Delegator; slot delegate = false; enddefine; define :class Delegate; enddefine; define :method thing(x : Delegate); 'delegate implementation' enddefine; define :method operation(x : Delegator); if delegate(x) and fail_safe(delegate(x), thing) then ;;; Return value is on the stack else 'default implementation' endif; enddefine; ;;; Default, without a delegate lvars a = newDelegator(); operation(a) => ;;; a delegating to itself (works because Delegator does not ;;; implement thing) a -> delegate(a); operation(a) => ;;; delegating to a freshly created Delegate newDelegate() -> delegate(a); operation(a) =>
Python
class Delegator: def __init__(self): self.delegate = None def operation(self): if hasattr(self.delegate, 'thing'): return self.delegate.thing() return 'default implementation' class Delegate: def thing(self): return 'delegate implementation' if __name__ == '__main__': # No delegate a = Delegator() assert a.operation() == 'default implementation' # With a delegate that does not implement "thing" a.delegate = 'A delegate may be any object' assert a.operation() == 'default implementation' # With delegate that implements "thing" a.delegate = Delegate() assert a.operation() == 'delegate implementation'