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:

      blog_post.publish

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.

Tuesday, December 09, 2014

tmux crash course

So you've probably heard about tmux and want to get started.  It might sound intimidating but after you follow this tutorial, you'll find that it's really not that bad.

Here's a basic crash course, written so that you can follow along, step-by-step.

Installation on OS X

brew install tmux

Basic commands

tmux new-session -s foo

Creates a session named foo.

Congrats! You are now attached to a session and you should see one tmux window.

A bit of terminology: you create a session which can have one or more windows, which we'll see below. Within a window, you can split it into panes.

(I'll use ^ to indicate "Ctrl", so ^b means Ctrl+b)

^b c
will create a new window.  You should see a status bar at the bottom of your terminal listing out the current windows. Do it again to create another.

Now you have multiple ways to switch between windows:

^b 1  switches to window 1
^b 2  switches to window 2
^b p  previous window
^b n  next window
^b w  choose window from a list
^b l  (lower case "L") go to last selected window

Next, you probably want to split your current window into panes.
^b "   Split vertically
^b %   Split horizontally

To switch panes:
^b o   Go to the "next" pane
^b up   Go to the pane above. Try left, right, and down as well.

Here's a cool feature of tmux that you might be familiar with if you've ever used screen.  You can detach from a session and reattach at a later time, with all of your windows and panes intact!
^b d .   Detach from current session

Finally, to reattach to a session
tmux attach -t foo   Reattach to a session named foo

Hope you found this to be useful.  Please let me know if you have any questions. Thanks!

Friday, November 14, 2014

TDD: Test behaviors, not methods

What I observed when a developer tests methods instead behavior
One of my favorite books, Growing Object Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce mentions that you should test behavior, not methods. The book, also referred to many as "GOOS", states on page 43:
We do better when we focus on the features that the object under test should provide, each of which may require collaboration with its neighbors and calling more than one of its methods.  We need to know how to use the class to achieve a goal, not how to exercise all the paths through its code.
 When this advice isn't followed
A few years ago, I coached a fellow developer in TDD.  Although I showed how to "write the code you wish you had" and how the tests drive the design, they refused to write the tests first, which is okay -- it was a big improvement from before when there were no tests.

My observations were that the specs described methods, and it was hard to figure out what the class actually did.  Also, one of the core behaviors of the class was never tested!

Another problem was when my team and I wanted to actually use an instance of the class, we couldn't quickly figure out which method, or set of methods, we should call to get the job done.  The specs read like a list of methods, not how an instance actually behaved.

What are your experiences? Do you prefer to test methods, or behavior?

Tuesday, November 11, 2014

Proxy Pattern -- one way out of many towards Clean Architecture


Earlier this year, I bought several of the Clean Coders screencasts, which motivated me to implement a clean architecture in Rails.  It also motivated me to read Uncle Bob's classic text, Agile Software Development: Principles, Practices, and Patterns. I've known about the SOLID principles, but the book really shines once you read past those initial chapters.


For example, here's a great quote from Uncle Bob Martin's PPP, regarding the PROXY pattern:
"It is a way to keep the business rule assets of your project separate from the implementation mechanisms that are currently in vogue." (page 345)
However, this isn't the only way to accomplish this. After reading and understanding the principles in the book, I've found that:
  • By following the D in the SOLID principles (Dependency Inversion Principle), it naturally leads you to design principles such as the PROXY pattern.
  • You have no fear of frameworks polluting your code because the SOLID principles will ensure that the dependencies point in the correct direction
  • Your tests will run extremely fast
  • The only slow tests you have will be integration tests with external resources (database, web services, file system, etc.) and frameworks
  • It's easier to upgrade since you only need to worry about integration failures, not the interaction between business logic and the new framework API. 
If you haven't read the entire book yet, I highly recommend checking it out.  It will change the way you think about writing software forever.

Friday, October 18, 2013

Book Review: iOS 6 Programming Cookbook By Vandad Nahavandipoor, O'Reilly Media

I reviewed this book as part of the O'Reilly blogger program.  

The format of the book consists of concise recipes which state the problem and show how to implement a solution with easy to follow code samples.  I love how the e-book has code samples in color with syntax-highlighting, and I found that the code was easy to translate to use with the Ruby Motion framework.  Of course, the recipes work fine with native Cocoa as well.

Being a cookbook, I don't think this book was intended to be read cover to cover, although I did just that when reviewing it. You could do that as well, but it might serve you better to use it as a reference. The good thing is that this book is organized almost like a non-cookbook; i.e. it has beginner topics in the first chapter(s) and gets progressively more advanced as you go on.

Although iOS 7 is available now, I would still highly recommend this book.
Read more about this book on its product page.

Saturday, October 06, 2012

Book Review: Code Simplicity: The Fundamentals of Software, by Max Kanat-Alexander, O'Reilly Media

Writing code seems like an easy task, and perhaps it is.  However, it can be difficult to write simple, clean code.

The book, "Code Simplicity: The Fundamentals of Software", explains:

  • Why do you want to write simple code?
  • How do you write simple code?
However, you will not find any code samples in this book.  While this may not be appealing to some readers, I did not feel that this lowered the quality of the book.  

It contains many guidelines and principles that experienced software craftsmen already know and might pass on to their apprentices.  Some of these principles:
  • Don't write code that isn't needed
  • Make the code easy to change
  • Comments -- should you add them? Why/why not?
A very experienced crafstman may not get much out of this book, but if you consider yourself a beginner or intermediate software developer, then I'd highly recommend this book.  It's full of great tips that will benefit you immediately and in the future.

You can find more about Code Simplicity on its product page on O'Reilly.