Interchange
is a way to define boundary objects. The class
defines the all required methods, then delegates the work to an
implementation. Implementations are be registered and used. A null
implementation is automatically generated and set as the
default implementation. This is useful in a few use cases:
- SOA setups where clients must be isolated from services (EX: different implementations in dev/test/production)
- Isolating different sub-systems
Here are some examples.
class Mailer
include Interchange.new(:deliver, :deliveries)
end
class SMTPDelivery
def deliver(mail)
# send w/SMTP
end
def deliveries
# check the email account
end
end
class SnailMail
def deliver(mail)
# print the mail and go to the post office
end
def deliveries
# go outside and check the mailbox
end
end
mailer = Mailer.new
mailer.register :smtp, SMTPDelivery.new
mailer.register :snail_mail, SnailMail.new
mail.use :smtp
mail.deliver some_message
mail.use :null # switch back to the null implementation.
These objects are useful when you have an interaction that needs to happen but implementations can vary widely. You can also use this as class if you don't like the instance flavor.
class Mailer
extend Interchange.new(:foo, :bar, :bar)
end
Mailer.register, :smtp, SomeSmtpClass
Since Interchange.new
returns a new module, you can call define
methods and call super
just like normal.
class Mailer
include Interchange.new(:deliver)
def deliver(mail)
raise "No address" unless mail.to
super
end
end
This is great when you have some shared logic at the boundary but not across implementations.
Add this line to your application's Gemfile:
gem 'interchange'
And then execute:
$ bundle
Or install it yourself as:
$ gem install interchange
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request