Codementor Events

Object-Oriented Programmers Should Love Microservices

Published Aug 29, 2019Last updated Feb 25, 2020

If you’re like most of the IT professionals I know, hearing the term “Microservices” makes you roll your eyes. Either you think it’s just part of someone playing Buzz-Word Bingo, or you think “I’ve heard all this before.” As popular and wide-spread as microservices architectures are, they still face a lot of skepticism and cynicism.

Nevertheless, microservices are being widely adopted and the likelihood is you’ll have to work in a microservices environment at some point. Before you go pull your hair out or go tell your boss why monads are simpler and easier to maintain, let me try to recast microservices in a way that might make more sense to you.

“Why” I can hear you thinking, “should I listen to you?”

Fair question. I’m a Lead Developer for a financial services company. I’ve been in the development industry for over ten years and almost all that has been working on some form of message-passing or loosely-coupled system. I’ve seen how they work well, and how they work poorly, and I understand why they’re desirable in general. Since microservices are a loosely-coupled, message-passing system, you can see why I’m comfortable with them.

It will also help for us to be on the same page. The skepticism of Buzz-Word Bingo is understandible, so here’s the definition I’m using of Microservices Architecture. From Wikipedia:

Microservices are a software development technique—a variant of the service-oriented architecture (SOA) architectural style that structures an application as a collection of loosely coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight. The benefit of decomposing an application into different smaller services is that it improves modularity. This makes the application easier to understand, develop, test, and become more resilient to architecture erosion.[1] It parallelizes development by enabling small autonomous teams to develop, deploy and scale their respective services independently.[2] It also allows the architecture of an individual service to emerge through continuous refactoring.[3] Microservice-based architectures enable continuous delivery and deployment.[4]

With that out of the way, I think I can sum up Microservices in a way that makes them seem a little less mysterious and address the skepticism somewhat. Ready? Here goes…

Microservices are the Object-Oriented Programming SOLID principles applied to your system architecture.

That’s all. Don’t believe me? Let’s take a look. What are the SOLID principles? Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion.

This one is easy. The Single Responsibility Principle says that a given class should have one, and only one, reason to change. That is, it should do one thing, do it well, and leave everything else to other components.

That is exactly what microservices advocates for a given service. A service should do one thing and only that thing. A service for gathering data should not also inspect or transform that data, for instance. By keeping services small and focused, we limit the circumstances under which each must change.

A class should be open to extension but closed to modification. Set aside the fact that four different developers will give you five different answers on exactly what this means for normal OOP. In microservices this is simple: my service is mine.

For general use scenarios, the service may need to be maintained or modified. If we have some generic piece of logic in a microservice which needs to change, of course we change it. Specialized business logic is a different matter.

You can add bridges, facades, adapters, and shims to provide any unit-of-work-specific or business-unit specific logic. Indeed, depending on business use, each of those components might be a necessary part of the overall system architecture.

In general, if a service does not offer functionality you need, you do not change the service; you write another which relies on the first.

A derived class should be able to be used, as is, in place of its parent.

In OOP, we talk about base classes or abstract classes and their children. If class Bar inherits from class Foo, then I should be able to use Bar whenever something asks for Foo.

How this applies to microservices is a little less clear than the others, so bear with me.

In the Open/Closed principle, I briefly mentioned using bridges, facades, adapters, or shims to add new specialized functionality to an existing service. From the standpoint of my service, that’s good enough.

From the standpoint of a client service we need to make sure the extra components can be used in place of the original. My client should not change how it calls for what it needs, the new component should be able to stand in for the primary service, allow the primary to do what it is designed to do, and then layer in whatever other functionality is needed – all with the calling client being none the wiser.

A client should not be forced to rely on methods it does not use. Put another way, lots of small interfaces are preferable to a single large interface.

From an OOP perspective, this means defining interfaces in line with the previous three principles. An interface should define one behavior-set. The implementation of an interface should be open to extension, but closed to modification. Derived interfaces should be able to be used in place of their base.

From a microservices standpoint, the same is true. Data gathering is not the same as data interpretation, analysis, or massaging. A client that needs to interpret a given data set may not need to do any deep analysis, but may need the data massaged or reshaped. Given this, a client application should not be forced to call a service which provides functionality it does not need or use.

Larger services tend to have more clients. A greater number of clients calling the same service leads to resource contention. This can be scaled, but that scaling is one-size-fits-all. Microservices allow such scaling to be more granular. If the component everyone calls is the data gathering piece, then it can grow independent of the other parts of the system. That is not possible with a single large service.

This is another principle which causes debate in the OOP world. Does it mean I should never program to concrete classes? Does it mean that the code on which my class depends should not create an instance of my class? The latter is obvious (I could feel you cringe from here), but the former is less-so.

Fortunately, microservices are much simpler. Program to contracts. Given a contract, I should be able to call for given functionality. A client should not need to care if a providing service has changed, if a shim or facade has been inserted between, or if some aggregate service is handling expanded functionality. As far as the client is concerned, it has an IDoStuff contract and an address for the IStuffDoerService. Given those two requirements, it can expect “stuff” to be “done”.

When we think of microservices in terms of OOP, they begin to make a lot more sense and objections become less serious.

Would you really complain, in your monad system, that you have to keep the rest of your system in sync with breaking-changes to a component? Of course not. And with microservices, we have options around versioning and service discovery which let us be even more forgiving.

Would you complain about writing error handling code in your monad classes? Of course not, so why complain about doing the same for your microservices?

I could continue, but I think you get the point. Microservices bring so much to the table, the fact is at some point you will work in a microservices environment. If you’re a doubter, I hope I’ve been able to help you change your perspective a little. Microservices are no more complex and are not harder to maintain than monads. They are differently complex and different to maintain.

Discover and read more posts from Allen Goodner
get started
post comments1Reply
Vikram S. Mathur (vsmathurcoin)
5 years ago

Thanks for sharing your valuable thoughts, coming from a VBA Programmer , I really mean it.