Inversion of Control: Putting All Together

We were talking a lot about Dependency Inversion Principle and the Main and Abstraction concept, however, we missed a pretty important point:

How all of this get together?

TRY IT YOURSELF: You can find this post source code here.

Dependency Inversion Series

The Boundaries of Main and Abstraction

Let’s talk about our first example, Service and Repository classes:

Service and Repository definitions

Now, let’s find the boundaries of Main and Abstraction:

Main and Abstraction boundaries

Okey, we know:

  • Abstraction: Service class and Repository interfaces belongs to this group. They have my business logic and rules.
  • Main: MySQLRepository belongs to this group. It is a detail, that I might change in the future.

NOTE: You might ask: why do I put the Repository interface in the abstraction zone instead of the main? well, that’s a good discussion for another moment.

Putting all together: the object creation challenge

Well, the Main and Abstraction concept talks about Main must be responsible of object creation, so, let’s add something to handle this:

A new Starter class

We have now the Starter class, this is our boot up. Let’s see how this class could look like in Java language:

public class Starter{

 public static void main(String[] args){

  Repository repository = new MySQLRepository();

  Service service = new Service(repository);

  //TODO: Use service object.........

 }

}

In Java, we must have somewhere a main method like these to start the whole program. We see now how our Starter creates objects and assign them as dependencies to other objects.

See how beautiful Dependency Inversion Principle is, Service class depends on Repository, not on a specific implementation, so, let’s move to different database.

public class Starter{

 public static void main(String[] args){

  //Repository repository = new MySQLRepository();
  Repository repository = new MongoDBRepository();

  Service service = new Service(repository);

  //TODO: Use service object.........

 }

}

As we see, we changed the whole database only refactoring one line of code in our Starter. Our business logic and rules are safe and they can be reused totally.

This is the power of Dependency Inversion Principle in its maximum expression

NOTE: You might ask, “good for Java, but in my language I cannot do this”, well, you might not know how your language really works, for instance, you have a similar Main class on .net, an index.js file on Node.js, an Activity class on Android, and so on. Moreover, if you really don’t find a explicit starter in your language, you should define one.

CAREFUL: You might think, changing a database in a software project is not as easy as I show here. Well, if it is not easy, it means your business logic and rules know too much about your database.

TRY IT YOURSELF: You can find this source code here.

Final Thought

We now can create complete decoupling systems using the Dependency Inversion Principle and the Main and Abstraction concepts, handling the object creation challenge.

However, our projects are pretty much complex than two clases, so, how do we handle complexity when we talk about decoupling? We use another common friend: Dependency Injection.

Moreover, complexity moves us to the zone where we need to make a trade off on how much we want our system to be decoupled.

If you liked this post and are interested in hearing more about my journey as a Software Engineer, you can follow me on Twitter and travel together.

10 comments

Leave a comment