If You Really Need to Know

Malina Tran
Tech and the City
Published in
3 min readJun 8, 2016

The road to maintenance nirvana is paved with classes that depend on things that change less often than they do.

- Sandy Metz, Practical Object-Oriented Design in Ruby, Chapter 3

Image courtesy of #WOCinTech Chat

Life lessons seem to conveniently align with coding principles. My personal philosophy is to disseminate information on a “need to know” basis. That is, if you absolutely need to know a piece of information, I will tell you. Otherwise, you can hang tight. (There is a splendid This American Life episode on this very topic).

After all, information overload is never a good thing. The more you know, the more likely you will–inadvertently or not–share that information with others or use it in a way that undermines the source and involved parties.

And similarly so in software applications. One of the ways that applications can become too overwrought, too entangled is through dependencies — instances of coupling between objects. An object has a dependency when it knows too much and has too much information, such as the name of another class or message (that you plan to send other than to self) as well as its arguments and order of those arguments. Metz points out an “especially destructive kind of dependency” — when an object knows another one and that one knows another one and pretty soon, messages and objects are chained together. That’s similar to real life. As a rule of thumb, each class should have the fewest number of dependencies: “a class should know just enough to do its job and not one thing more.”

Figuring out which information needs to be shared by objects and methods is a particularly useful skill. (One that I am working on because, admittedly, I will overshare; I am not that pragmatic of an information guardian). Metz suggests a technique that is often known as a service injection or dependency injection. This technique passes necessary dependencies to the constructor of an object (particularly if there have been explicit dependencies on another class). One of the key solution to handling dependencies is to isolate.

If dependencies cannot be removed, they should be isolated and easily identifiable. Metz’s colorful language depicting dependencies as alien bacterium is pretty awesome: “dependencies are foreign invaders that represent vulnerabilities, and they should be concise, explicit, and isolated.” Here are some ways to quarantine the alien bacterium:

  • Isolate instance creation. Expose the dependency, but reduce its potential effect on the rest of the class. Encapsulate its instantiation in the constructor or a separate method altogether.
  • Isolate “vulnerable” external messages. External messages are sent to some other object other than self. In complex code, dependencies are particularly vulnerable to being broken. Instead, reduce that possibility by wrapping it in its own method, however simple and straightforward it may be. It also helps with DRY’er code.
  • Handle initialization arguments with hashes. Rather than pass argument values (which must be in the correct order), pass in just one argument as a hash that contains all of the inputs. This will also add verbosity as it becomes very explicit which values you’re retrieving and can be a life-saver if you’re passing tons of arguments.
  • Have explicit defaults for constructors. I have traditionally used booleans to set defaults, in the event that no argument is passed. However, it is recommended to use `.fetch` since it expects the key you’re fetching to be in the hash and doesn’t automatically return `nil` when it fails to find the key.
  • Change the direction of the dependency. Here goes another life lesson (courtesy of Metz): depend on things that change less often than you. Reversing dependencies do no harm, but they should be introduced in more abstract classes which are more stable and less likely to change. Abstraction is derived from concrete classes, but are dissociated from any instance, which make them more powerful. Concrete classes that we create will change as we develop them but more abstract ones have a longer staying power.

And there you have it: what you need to know (hopefully) to manage dependencies!

--

--