interfacelike design pattern in ruby
Strategy pattern could be applied here
def Provider def contacts raise "Abstract method called" endendclass Google < Provider def contacts data = # Google API call endendclass LinkedIn < Provider def contacts data = # LinkedIn API call endendclass Impl def initialize(provider) case provider when :google @provider = Google.new when :linkedin @provider = LinkedIn.new else raise "Unknown provider" end end def contacts @provider.contacts endendimpl = Impl.new(provider)impl.contacts
There are several good approaches to this. One is to encapsulate the different functionality into modules:
module Google def contacts puts 'contacts from Google' endendmodule LinkedIn def contacts puts 'contacts from LinkedIn' endendclass Impl def self.create provider o = new o.extend(provider) endendImpl.create(Google).contactsImpl.create(LinkedIn).contacts
Output:
contacts from Googlecontacts from LinkedIn
Here the create
method on Impl
is a factory method for Impl instances that adds in the methods from the given module. Just make sure that the modules implement the same method names and return compatible values.
Modules are usually used to exclude common behavior of multiple objects. I believe that all you need in this case is duck-typing. Just implement method contacts
in all classes that would share interface in Java solution.
Please note that this solution allows you to keep objects of different types in a single collection, and while you iterate over them (or in any other way you would like to use these common-interface objects) you just call this contacts
method, not caring what type they really are.
If you need some common behavior in all classes implementing this interface you can create module that would base on existence of contacts
method, and include it in all classes that could use it.