Growing Object Oriented Software Guided by Tests , chapter 6— TLDR

Nir Orman
5 min readSep 23, 2021

If you haven’t read chapter 5 yet, I recommend going back to it now :)

Get some coffee, this chapter is filled with new terms and rules, let’s drill in!

Object Oriented Style

It is more important that the code will be easy to maintain than that the code will be easy to write.

Separate your business logic from the technical interface which it relies on, such as databases, streaming platforms, etc. We need an adaptor that will provide:

  • Separation of concerns- when I change something in the infrastructure (like, the logging tool I use), I don’t want to have to make changes in the whole code base. An adapter could prevent that.
  • A higher level of abstraction- I want my entity saved to the DB. When I read the code of the business logic that does that, it doesn’t matter which db it’s writing to and how it’s done. An adapter can provide that abstraction. It’s easier to deal with a complex system that has a lot of details when it hides the details, and helps you look at things from a macro perspective.

A typical application will have a business domain (your business logic), and a technical interface (web services, message brokers, databases, user interfaces and reporting abilities). We would want to separate them cleanly.

Encapsulation vs. Information hiding:

They are not the same! The difference is pretty hard to grasp. Pay attention!

Encapsulating is making sure that the object is only affected through its API. If it’s badly encapsulated it’s hard to tell where the object was created and where its content is used.

Here are some Do’s and Don’ts:

Don’t do’s:

1. Don’t share a reference/pointer to a mutable object.

2. Don’t use global variables!

3. Don’t use singeltons!

Do do’s:

  1. Use immutable values (like ‘val’ in Scala, instead of ‘var’ for example).
  2. Define which API the object needs to expose: encapsulate the access to the internals through the API and hide the details from the rest of the system. This will save the readers time, they won’t have to look at the lower level of implementation in order to understand your code.
  3. When you’re writing code that is for communication between objects — use the “message passing” style, which means, define the API well and use it.
  4. When you’re writing code within an object, write it in the “functional style”: build it up from methods and values that have no side effects.

We’re gonna go over some rules now:

The One thing Rule

Each object should only have a SINGLE responsibility. Just ONE☝.️ Photo by Franco Antonio Giovanella on Unsplash

I recall reading this principal in the Clean Code book too (if you haven’t read it, you should). But the gist of the rule is, that every object should have a single responsibility.

You’ve broken the rule if when you describe it you use “and”/ “or” words. That means it’s doing too many things and it should be split into different objects/ classes.

Great! So we have objects with a clean API that communicate with each other. How are they communicating?

  • One object could be dependent on its peers. If it needs its peers, they should be passed into it in its constructor. The dependencies are needed in order to create the object, don’t create the object without it and then pass them along later, they are required, it doesn’t make sense without them!
  • One object could have peers that adjust it according to the needs of the system. (like when a user changes the currency or the language of the site). It’s also called the Strategy pattern. When the object is composed of other components, the adjustments could affect those too. You could start the object with a safe default and then assign it later using the API.
  • One object could notify its peers when there was a change in its state.It fires an event (like a kafka event for example) and whoever wants to listen, is welcome. This helps decouple objects, listeners don’t know and shouldn’t care about the way the event was caused, and the event sender doesn’t have to take care of who listens to it. In short, Fire and Forget. You could add methods that enable changing the notifications and add or remove listeners.
Fire and forget [Head Gamer GIF By Power Unlimited]

My favorite quote:

The composite object’s API must hide the existence of its component parts and the interactions between them, and expose a simpler abstraction to its peers.

“Think of a mechanical clock: It has two or three hands for output and one pull-out wheel for input but packages up dozens of moving parts.” page 53 of Growing Object-Oriented Software Guided by Tests

The “Composite simpler than the sum of its parts” Rule

Aristotle (the Greek philosopher) who said “The whole is greater than the sum of its parts”

By following this rule of thumb, of trying to make the composite object simpler than the sum of its parts, you’ll see that the more your code grows, the more you need to raise the level of abstraction, and hide more information.

if the composite object is not simpler, you need to hide more information.

The “Context Independence” Rule

Are you hiding too much information? Are you hiding the wrong information?

The objects should not be aware of the system in which they operate. If an object needs to be aware of an external context, then that context should be passed into it. If it needs it permanently, then it should be passed in the constructor. Otherwise, it could be passed into the method where it is needed.

The “One Domain Vocabulary” Rule

Don’t use a term from another domain’s vocabulary, unless you’re a bridging layer. If you’re doing it right, then similar objects would often be created together and composed in the same place, so you wouldn’t have to use a vocabulary of another domain.

Russian dolls

We need to have a structure of nested domains, like a “Russian doll”. We should not hide details of one level in another level. If some detail is needed in the “internal” doll, then it should be packaged up and passed in from a level that understands the external configuration.

The “Russian Doll” — be careful, when intending to encapsulate, (which is a good idea in general) you might accidentally hide information in an “inner” doll, instead of putting outside and passing it in.

That’s it!🥳 We’re now on page 81 on the digital copy (56 in the physical copy). I have compressed 3,242 words into 1,110 (compression rate 2.92🤘).

Follow me on LinkedIn, Twitter and Medium to know when chapter 7 is summarized.

--

--

Nir Orman

Innovation lover, Technology geek, Enthusiastic Software Engineer