Thursday, September 03, 2015

Using Graph of Objects as the Unit of Reuse


I was refactoring code from an old project. It had used lot of stubs and mocks. The resulting design was not reviewed after taking a break from coding. But the methods that use the same variables were grouped together. This could also be due to the fact that I was coding alone. TDD and Pair-Programming go together. So when I revisited the code after a few months break, I was able to look at it from a fresh new perspective.

By rewriting code from scratch, while developing the gem, you are forced to think about the user of the library when you have to write the README, gem summary and description in the gem spec file. This  forces you to think about the functionality of the gem and how it can be used from a user’s perspective. Coming up with a concise description of the gem also defines how focused it should be, this helps in developing a cohesive gem.

By using structs instead of stubs and mocks, the code became more cohesive. During the rewriting process, I constantly asked myself :

“How likely is this going to change if Rails changes?”. 

I decided to keep dependencies such as product_id, product_name and anything that did not call ActiveRecord methods as safe bets because I can define methods with the same name on those objects.

Making the objects cohesive was a conscious choice, I asked myself :

“Is this data operating on this object all the time?”. 

If not, I split them so that they did operate with the object all the time.

The private methods were moved to small highly cohesive classes that can be composed to accomplish higher level tasks. The Micro Gem packages a group of objects that collaborate to accomplish one task that is done very well. The objective is not to reuse objects in different contexts but to isolate dependencies and provide a specific service to a developer. It encapsulates the knowledge required to implement something and makes it easy for other developers to utilize the service provided by the group of objects collaborating together.

Developing a quality product is challenging. There is no silver bullet. There is no one right way to do it. It’s like a stereo dial, you have to try different approaches and learn what combination works best for you. It could be top-down, bottom-up or combination of top and bottom up approaches with, some upfront design, TDD, PPP etc.

Took related private methods and moved them into a small classes with well defined interface that encapsulates the knowledge about accessing the external data structure, Paypal in this case.

About Not Aiming for Object Reuse

By focusing on a group of objects that provide one service, we avoid the following questions that can lead to confusion about the code base.
  1. Who are the clients of this class?
  2. What is the impact of changing the class?
  3. Which use cases need this class?
Confusion is the enemy of clarity and leads to difficulty in maintenance. Using a graph of objects that has single well defined purpose is a better unit of reuse in the long term for ease of maintenance.