Modularization and dependency management: three steps to better code
Tags: architecture, cleancode, readability
Published: 2017-09-08 11:34:41

---
title: "Modularization and dependency management: three steps to better code"
published: true
description: 
tags: architecture, clean-code, readability
---

If you ask me, what's a single most important thing in writing good code, I'd reply: "Modularization and Dependency Management".

Well, actually,Â that's two things. Sorry about that! But they are two sides of the same coin, and you can't have one without the other, if you want to your code to be nice and clean.

<!--more-->

Long story short: modularize the code and let every part of it serve only one specific purpose.

That's one most important quality of the code: proper modularization and proper dependencies between modules, or blocks.
<h1>The ultimate recipe for good code</h1>
That's oneÂ loud header, but the steps are actually pretty simple and even might look obvious, when you think of it.

Here it goes.

<hr />

<strong>Any module of the application, however big or small, should follow these three simple rules:</strong>
<ol>
 	<li>It should have one specific responsibility.</li>
 	<li>If other blocks are going to use it, they must use its API. They must not have access or any knowledge of this block's internals.</li>
 	<li>If it uses other blocks, it should use their APIs.Â It must not use or rely on any of their internals.</li>
</ol>

<hr />

<h1>What are dependencies and APIs?</h1>
An API is an interface or a protocol of a given service which lets you useÂ this service.

And implementation details of that service would be everything inside it that lets it do its work. Cogs and wheels.

For example, if we were talking about a big web application, a service AÂ could call the REST API of a service B. In this case the API of the service B would be, well, the REST API - all these nice POST, PUT, GET and DELETE methods which service B provides, as described in its documentation. (You do have documentation, right?)

Of course, it can be SOAP API too, or any other sort of API. The point is to have a bunch of defined endpoints which you can call and this way ask the service to do stuff.

InÂ any case, we could say that service A <em>depends on, </em>or<em> has a dependence on</em> service B. Probably it's called a "dependency" because A can't do its work without B's help.

If we are talking about classes, it would mean class A calling another class B'sÂ method. Then the API of that class B would be - its public methods. The internals of class B are its protected and private methods, and class A and the developer of class A areÂ not supposed to know anything about them.

If it was about functions, it would be one function A calling another function B. The function's API is its definition: name, arguments, and return type. The internals of the function is its specific implementation.

In general,Â if one of your modules needs help from another one to do its work, it's a dependency.
<h1>Diagrams with rectangles and arrows</h1>
Let's have a look at the following picture. The modulesÂ hereÂ have very clear dependencies, and a small number of them, so the whole picture is very easy to understand. Also note that one module depends on other module's API, not on its implementation details.

<img class="wp-image-535 size-full" src="http://smartpuffin.com/wp-content/uploads/2017/05/New-Mockup-1.png" alt="Module 1's implementation depends on APIs of Module 2 and Module 3. Module 2 has dependencies on Module 3 and Module 4. Module 3 also depends on Module 4." width="560" height="461" /> Modules and their dependencies

And, though it's not reflected on this abstract picture, every module has its own piece of work to do. It doesn't do two or three things at once. No multitasking.
<h3>We need to go deeper!</h3>
You'll notice you can go deeperÂ recursively, where eachÂ bigger block has smaller parts, which have their own small, but clearly defined responsibilities.

Let's zoom in into Module 2 from the previous picture. It consists of smaller modules, and I called them submodules. The Submodules also have dependencies on each other and on other bigger modules outside of Module 2.

<img class="wp-image-537 size-full" src="http://smartpuffin.com/wp-content/uploads/2017/05/New-Mockup-2.png" alt="Module 2 consists of 3 submodules. Submodule 2.1 depends on its fellow Submodules 2.2 and 2.3, but also on bigger Module 3. Submodule 2.2 depends only on Submodule 2.3. Submodule 2.3 depends on Module 3 and Module 4." width="844" height="720" /> Module 2 in depth

But they still follow our Three Principles: they use each other APIs, they don'tÂ flash out their internals, and they modestly don't peek into other modules' internals.

Of course, you can go even deeper and draw a diagramÂ of any submodule. If done properly, it would be the same in essence.

These principles are important on any level.
<h1>How does it help?</h1>
Firstly, the code thatÂ follows our three rules isÂ easy to understand. These rules make the code readable, you can follow it through and understand what it does. You can go deeper into details or step backÂ and look at the bigger picture. On any level, you'll find the same neat structure.

You can explain it to someone else. You can even easily draw a picture like the ones shown here, and show it to your colleagues.

Secondly, if it's easy to understand, it's easy to change when needed.

Thirdly, you can localize your change so that you'll edit only parts that need the change. If you have your APIs in place, you can just change the implementation, and all dependent modules will stay blissfully ignorant.
<h5>Big Talks aboutÂ Architecture</h5>
You can easily explain it to your colleague on any level of details. If you're talking to your manager or speaking in a conference, you'll draw a diagramÂ withÂ biggest blocks, for example, database(s), server application(s), and client application(s). Everyone will understand your system quickly and, of course, will stand in awe before your genius! :)

Ever noticed how pictures in articles and talks about Big Systems Architecture have the very similar presentation: usually, blocks and arrows, like here, in this article?

Noticed how arrows always go in one general direction?

It's because this principle is applicable to any level of abstraction in software development.
<h5>Small talks about smaller things</h5>
IfÂ a fellow developer explains to youÂ the details of the feature they just implemented, they will probablyÂ talk about smallÂ blocks. It could be a couple of classes with five functions or so. The classes and the functions would depend on each other, just like Databases and Servers.Â And if you try to draw a diagram of them to understand them better, it'll still look the same.
<h3>Refactoring</h3>
Now, what happens if you want to rewrite a piece of code? Let's you'd like to improve the <em>Submodule 2.3</em> from that picture.Â But <em>Submodules 2.1</em> and <em>2.2</em> depend on it! Is it wise to touch it? Won't theÂ others break?

The best thing is - no oneÂ outside of <em>Submodule 2.3</em> cares what's inside it! All modules which use it know only about the API. This means you can change its insides however you want.

Exactly the same thing goes about bigger modules. <em>Module 1</em> depends on <em>Module 2</em>'s API. It doesn't know a single thing about <em>Module 2</em>'s internals. It doesn't care about anyÂ Submodules and their dependencies but its own.

Now, what happens if you find the whole <em>Module 2</em> ineffective and want to rewrite it? You guessed it! You just change <em>Module 2</em>'s internals in any way you like, but all other Modules won't notice. You can pull it off because you modularized the code properly andÂ managed dependencies properly. Congratulations!

And again, this goes on all levels.
<h5>Example of a small refactoring</h5>
Say, you have a method that loads user names from the database, sorts them, and returns them to display somewhere in the user interface.

It's quite possible your small diagram with modules and dependencies would look like this.

<img class="alignnone size-full wp-image-541" src="http://smartpuffin.com/wp-content/uploads/2017/05/New-Mockup-4.png" alt="" width="1125" height="488" />

Noticed we're using bubble sort in here? When you have five user names, it's all fine. When you have more, it becomes a problem.

So,Â you might want to rewrite your <em>swap()</em> function to make it more effective.Â Then all your other code stays totally the same! You just change the internals of the <em>swap()</em> function, and the <em>sort()</em>Â method still works. And the <em>getUserNames()</em>Â works too. And the code that displays the results ofÂ <em>getUserNames()</em>.

Or, maybe you want to change the bubblesort to something else, a bit more effective. Then you'll change the implementation of the <em>sort()</em> function, but <em>getUserNames()</em> won't notice.

See? You make changes only inÂ necessary code parts, but all other parts that depend on it can stay the same. Neat!
<h5>Example of a big scale refactoring</h5>
On a bigger scale, managing separate blocks is even more important, than on a smaller scale!

Let's imagine you have an application with some two server-side applications, one client, and a database. The architectural diagram might look like this:

<img class="wp-image-540 size-full" src="http://smartpuffin.com/wp-content/uploads/2017/05/New-Mockup-3.png" alt="" width="1040" height="403" /> Client Application depends on two Server Applications, they both depend on the Data Access Layer, and it depends on the Database

Now, let's say it's been working for some time, and everything was good, but now the business grows, and you want to optimize the Server Application. If you want toÂ rewrite the Server, you just need to keep its APIs intact. Then all other parts will stay the same, because you took good care about keeping the APIs.

By keeping the APIs the same, you have several advantages:
<ul>
 	<li>You don't have to change the client code.Â  You have isolated part of your work, and you don't need to do more. That's nice, isn't it?</li>
 	<li>You don't have to provide everyone with the updated Client application. It's not always possible. Imagine that your application is a desktop or a smartphone app. Not everyone updates an app the very instant the developers released a new version!</li>
</ul>
<h1>Why it's very-very important on a bigger scale</h1>
Why else are modularization and managing dependencies very important on a bigger scale? Because it's harder to fix mistakes.

If you made a mistake and tied the dependency knot tighter than needed between your two private functions in a class, that's not a big problem. You can untie it in ten minutes. Easy.

If there're two classes tied together so that there's a circular dependency, you'll probably have to spend a couple of hours trying to understand what's happening and how to untie them. Perhaps, you'll have to introduce a third class to solve the problem, and maybe write some tests. Still, hot tooÂ hard to solve.

But if you've done something wrong with your architectural-scale blocks, it's not a small thing anymore! If you forgot toÂ split your code into server-side and client-side libraries, you'll spend LOTS of timeÂ tidying, cleaning, and also being angry and swearing.

If it hasn't been done in the first place, whenÂ the architecture was being developed, then it's going to be only worse with time. New developers are not going to understand the whole picture, they are going to introduce more and moreÂ badly modularized, highly dependent code, and it'll become a complete mess.

This state is famously called <em>"spaghetti code"</em>, when all modules are tied and mixed together like spaghetti on a plate.

The development of new features will slow down and will keep slowing down with time. The bugs will multiply, and fixing them will become increasingly difficult.

At one point the development process might stop altogether.

To help you avoid this entangled hell, here'sÂ this simple recipe again:
<h1>The ultimate recipe for good code - again</h1>
<strong>Any module of the application, however big or small, should follow these three simple rules:</strong>
<ol>
 	<li>It should have one specific responsibility.</li>
 	<li>If other blocks are going to use it, they must use its API. They must not have access or any knowledge of this block's internals.</li>
 	<li>If it uses other blocks, it should use their APIs.Â It must not use or rely on any of their internals.</li>
</ol>