interfacelike design pattern in ruby interfacelike design pattern in ruby ruby ruby

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.