Wednesday, March 11, 2015

Dependency Inversion Principle in Practice

Ever notice how the requirements of an API affect the design of your classes? Well, they shouldn't!

Consider the requirements for using resque.  Please don't misunderstand; resque is a great library which abstracts away the details of asynchronous execution.  In case you weren't aware, its #enqueue method accepts a class name followed by an arbitrary number of (zero to many) arguments.

The fact that it does this should have no effect on the design of your classes.  Yes, you need to make a #perform method that then takes zero to many args, but again the design of your class should not be affected by this requirement.

For example, I've seen code where everything became a class method because of resque's requirements.

To get around this, you'll write an adapter layer which translates between resque and your code.  You don't have to be stuck with class methods.  Design your own code without Resque in mind, then hook it up at the last possible moment.

Another example is in Rails codebases:  how many times have you seen -- or even written yourself --

     some_model.update_attributes(foo: 'bar',  panda: 'bamboo')

when something like:


would make more sense?

You can hide the details of ActiveRecord's API behind domain-specific, intention-revealing method names that you choose.

What are your thoughts on the Dependency Inversion Principle, especially when writing Ruby?

The inspiration from this post came from several ideas:

Wednesday, January 14, 2015

Ignore files without modifying .gitignore

Brief note: Thanks to this episode of the Ruby Rogues featuring John Sonmez, I've been inspired to blog a little more often.

Problem: You use git and might use some tools that generate files that other people on your team don't use.  For example, you might use vim and create a Session.vim file.  Rather than clutter the .gitignore with these files, there is another elegant solution.

Solution: You can put these entries into .git/info/exclude and git will ignore them, just as if you had placed them in .gitignore.  There is one difference, however: .gitignore is usually committed, but .git/info/exclude is a file that exists in your working copy of the repo and it is not committed.  Therefore, if you clone the repo to another location on your computer, you'll have to add the entries to .git/info/exclude again.

There are advantages and disadvantages to each method -- don't fret about it too much though.  You can always revert your changes and try the other technique.