Created
June 30, 2012 03:19
-
-
Save seangeo/3022012 to your computer and use it in GitHub Desktop.
Using decorators to extend objects with roles without modifying the original object. A possible alternative to dynamic method binding described in Clean Ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Jim Gay's new book, Clean Ruby (http://clean-ruby.com), has a section on dynamically binding | |
# methods to objects with roles in a DCI context. He does this in a way that doesn't modify the | |
# original object, unlike extending the object with a model does. I found the solution clever | |
# but maybe a little bit unclear (but it's the first iteration of this part of the book, so I'm | |
# sure it will become more convincing later :). | |
# | |
# This is an alternative to that solution which uses Module extension on a simple wrapper/decorator | |
# object. The module's methods are added to the wrapper and it behaves as though the original object | |
# has been extended with the role, but the original is untouched. I haven't really seen this solution | |
# to the role extension problem anywhere else, but I'm sure I'm not the first to suggest it. | |
require 'delegate' | |
module Transferrable | |
def transfer_to(amount, to) | |
self.decrement(amount) | |
to.increment(amount) | |
end | |
end | |
source = Account.find(1) | |
destination = Account.find(2) | |
# This would go in a Context that needs the role. | |
transferrable_source = SimpleDelegate.new(source).extend(Transferrable) | |
transferrable_source.transfer_to(10, destination) | |
source.transfer_to(10, destination) # raises NoMethodError, that's good! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment