Adaptor makes it easy to implement the Adapter pattern in Ruby.
Add this line to your application's Gemfile:
gem 'adaptor'
And then execute:
$ bundle
Or install it yourself as:
$ gem install adaptor
You can use the library in single-adaptor mode:
module DocumentProcessor
class Pdf
include Adaptor
def self.supports?(document)
document.mime_type == 'application/pdf'
end
def initialize(document)
@document = document
end
def build_thumbnail
# something with @document
end
end
class Word
include Adaptor
def self.supports?(document)
document.mime_type == 'application/msword'
end
def initialize(document)
@document = document
end
def build_thumbnail
# something with @document
end
end
end
module DocumentProcessor
include Adaptor::Loader
register Pdf, Word
end
# You can use #load_adaptor! if you want to raise an
# Adaptor::NoAdaptorError when no adaptor is found.
thumbnail = DocumentProcessor.load_adaptor(document).build_thumbnail
If it suits your use case, you can use multiple-adaptor mode:
module NotificationProcessor
class Email
include Adaptor
def self.supports?(notification)
notification.user.email.present?
end
def initialize(notification)
@notification = notification
end
def deliver
# ...
end
end
class Sms
include Adaptor
def self.supports?(notification)
notification.user.phone.present?
end
def initialize(notification)
@notification = notification
end
def deliver
# ...
end
end
end
module MultipleAdaptorLoader
include Adaptor::Loader
register Email, Sms
end
# You can use #load_adaptors! if you want to raise an
# Adaptor::NoAdaptorError when no adaptors are found.
NotificationProcessor.load_adaptors(notification).each(&:deliver)
Note that there is no limit to the number of arguments you can pass to the adaptors' .supports?
and .new
methods. Here's an example that checks support only with one argument, but initializes
with multiple:
module DocumentProcessor
class Pdf
include Adaptor
def self.supports?(document)
document.mime_type == 'application/pdf'
end
def initialize(document, options)
@document = document
@options = options
end
def build_thumbnail
# something with @document and @options
end
end
class Word
include Adaptor
def self.supports?(document)
document.mime_type == 'application/msword'
end
def initialize(document, options)
@document = document
@options = options
end
def build_thumbnail
# something with @document and @options
end
end
end
module DocumentProcessor
include Adaptor::Loader
register Pdf, Word
end
# You can use #load_adaptor! if you want to raise an
# Adaptor::NoAdaptorError when no adaptor is found.
thumbnail = DocumentProcessor.load_adaptor(document, stamp: true).build_thumbnail
As you can see, whatever you pass to .load_adaptor
or .load_adaptors
will be forwarded to
.supports?
and .new
, according to the methods' respective arity.
Bug reports and pull requests are welcome on GitHub at https://github.com/aldesantis/adaptor. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Adaptor project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.