← Back to Upcase

Class interfaces are a smell - example?


(Bruce) #1

So I read tip #5 in this article by Solnica. He says “I use class-level interfaces exclusively for building objects. It’s much easier to lower the coupling this way.” How is that different from a traditional ruby class such as below (or is it different)? My understanding of the interface pattern (a la Java) is that you specify methods in an interface so that a class which implements the interface must contain those methods.

class ZipCodeClass
  def initialize
    @zip_code = "10048"
  end
  def set_zip_code(zip_code="10048")
    @zip_code = zip_code
  end
end

(Pedro Moreira) #2

I think the point is about class level interfaces, so following your example something like:

class ZipCode

def self.set_zip_code(args)
  # zip cody stuff
end

So Solnica believes, and I fully agree, that class level interfaces - or methods - are best reserved for creating new instances, something like:

class ZipCode
  def self.from_user_address(user_address)
    new(user_address)
  end
end

In this example, we use a class level interface that can perhaps improve clarity on the place where we call it, maybe a controller on a Rails app:

class AddressesController < ApplicationController
  def create
    user_address = current_user.addresses.create!(address_params)
    Zipcode.from_user_address(user_address)
  end
end

This is just a hacky example. You might want to read https://robots.thoughtbot.com/meditations-on-a-class-method for a wonderful explanation and insight on this.

Hope this helps


(Bruce) #3

Thank you @pedromoreira, that was enlightening, particularly the bit in the blog post:

The simplicity of the snippet is a reminder to use abstractions on the same “level”. Create an instance and call a method on that; perhaps in the instance’s #run method, it will instantiate a few more objects and call a method on those; and so on. Short methods all the way down, explained with clear but concise names.