“Shy” Code

Leena
Continuous Delivery
3 min readDec 6, 2017

Dependencies in the code are what makes the software less maintainable. We cannot avoid dependencies altogether, but there are techniques to reduce it to the minimum with the right abstractions.

Tell, Don’t Ask

The above code has a high dependency on the wallet class, and it violates the principles Tell, Don’t Ask and Law of Demeter.

In my experience, object-oriented code is easier to understand and maintain if it is written in a “Tell, Don’t Ask” style. In this style, objects make decisions using only the information that they hold internally or that they receive as message parameters; they do not make decisions using information that is held by other objects. That is, objects tell each other what to do by sending commands to one another, they don’t ask each other for information and then make decisions upon the results of those queries. The end result of this style is that it is easy to swap one object for another that can respond to the same commands but in a different way. This is because the behaviour of one object is not tied to the internal structure of the objects that it talks to.
(~Nat Pryce, Excerpt from the Growing Object Oriented Software Guided by Tests book)

The idea is to make sure that each module/class makes decisions using the information that it has internally than trying to make decisions using information held by other objects. In Pragmatic Programmer book, it is mentioned that the code should be “shy”, i.e. don’t reveal yourself to others, and don’t interact with too many people.

Let’s rewrite the above code to make it “shy”:

In the above version, the Customer “tells” the wallet to deduct the amount than deciding on behalf of Wallet. And Wallet has become “shy” too.

Beyond Object-Oriented Design

Even though the SOLID principles are referred as a guideline for designing Object-oriented code, it can be applied to other programming paradigms or systems design. Functional programming might inherently implement many of the principles or makes it easier to implement.

And these principles can be applied at the system level or service level too. E.g., while designing a service, be it a Micro-Service or a service as per Service-oriented architecture [SOA], applying SRP helps to define the boundaries of the service or SRP can be used for splitting the big system into small independent pieces. And by making the modules “shy” helps us to make them more cohesive and less coupled.

I liked the analogy that Chad Fowler used in the talk, Growing Old, in which he compares the system design to Homeostasis —equilibrium or the balance of bodily functions. E.g., lots of cells die in our body may be in every second. And that's by design, and our body [which is a very complex system by itself] knows how to balance it well provided we need to take good care of our body.

If we’ve to design our systems the similar way, we need to design them as thin as possible with high reliability. We need to maintain the system well too.

RubyConf 2017: Keynote: Growing Old by Chad Fowler

Considering that “Change is the only constant”, Continuous Design is the way to keep our systems well maintained — to manage both Technical Debt and Product Debt. And to keep our systems flexible, make the changes small and reversible.

Update: Pat Shaughnessy, author of the book Ruby Under a Microscope, mentioned in twitter that he was reminded of his post on the similar topic, but with a slightly different title 😄 — Use An Ask, Don’t Tell Policy With Ruby. Read the post as well as the comments, it is interesting.

--

--

Leena
Continuous Delivery

Co-founder/CTO @ PracticeNow, Bangalore, India. A strong believer of lean principles, an evangelist and practitioner of Continuous delivery