CodeGym/Java Course/Module 3. Java Professional/How to loosen coupling between software modules

How to loosen coupling between software modules

Available

8.1 Decomposition is everything

For clarity, a picture from a good article "Decoupling of Object-Oriented Systems", illustrating the main points that will be discussed.

Decomposition

Do you still think that designing an application architecture is easy?

8.2 Interfaces, implementation hiding

The main principles for reducing the coupling of the system are the principles of OOP and the principle of Encapsulation + Abstraction + Polymorphism behind them.

That is why:

  • Modules should be "black boxes" for each other (encapsulation) . This means that one module should not “climb” into another module and know anything about its internal structure. Objects in one subsystem should not directly access objects in another subsystem.
  • Modules/subsystems should interact with each other only through interfaces (that is, abstractions that do not depend on implementation details). Accordingly, each module must have a well-defined interface or interfaces for interacting with other modules.

The principle of "black box" (encapsulation) allows us to consider the structure of each subsystem independently of other subsystems. The module, which is a "black box", can be relatively freely changed. Problems can arise only at the junction of different modules (or a module and an environment).

And this interaction must be described in the most general (abstract) form, that is, in the form of an interface. In this case, the code will work the same with any implementation that conforms to the interface contract. It is this ability to work with different implementations (modules or objects) through a unified interface that is called polymorphism.

That is why Servlet is an interface : the web container does not know anything about servlets, for it these are some objects that implement the Servlet interface and that's it. Servlets also know a little about the structure of the container. The Servlet interface is that contract, that standard, that minimum interaction that is needed to make Java web applications take over the world.

Polymorphism is not at all the overriding of methods, as is sometimes mistakenly believed, but first of all, the interchangeability of modules / objects with the same interface or “one interface, many implementations”. To implement polymorphism, the inheritance mechanism is not needed at all. This is important to understand because inheritance in general should be avoided whenever possible .

Thanks to interfaces and polymorphism, it is precisely the ability to modify and extend the code without changing what is already written (Open-Closed Principle) is achieved.

As long as the interaction of modules is described exclusively in the form of interfaces and is not tied to specific implementations, you have the opportunity to absolutely “painlessly” for the system replace one module with any other that implements the same interface, as well as add a new one and thereby expand functionality.

It's like in the LEGO constructor - the interface standardizes the interaction and serves as a kind of connector where any module with a suitable connector can be connected.

The flexibility of the designer is ensured by the fact that we can simply replace one module or part with another with the same connectors (with the same interface), as well as add as many new parts as we like (at the same time, existing parts are not changed or altered in any way).

Interfaces allow you to build a simpler system, considering each subsystem as a whole and ignoring its internal structure. They allow modules to interact and at the same time know nothing about the internal structure of each other, thereby fully implementing the principle of minimal knowledge, which is the basis of loose coupling.

The more general/abstract the interfaces are defined and the less restrictions they impose on interaction, the more flexible the system. From here, one more of the principles of SOLID actually follows - the Interface Segregation Principle , which opposes “thick interfaces”.

He says that large, bulky interfaces should be broken down into smaller, more specific ones, so that clients of small interfaces (depending modules) only know about the methods they need to work with.

This principle is formulated as follows: “Clients should not depend on methods (be aware of methods) that they do not use” or “Many specialized interfaces are better than one universal one”.

It turns out that weak connectivity is provided only when the interaction and dependencies of modules are described only with the help of interfaces, that is, abstractions, without using knowledge about their internal structure and structure. And in fact, encapsulation is thus implemented. Plus, we have the ability to expand / change the behavior of the system by adding and using different implementations, that is, due to polymorphism. Yes, we again came to OOP - Encapsulation, Abstraction, Polymorphism.

8.3 Facade: module interface

Here an experienced programmer will ask: if the design is not at the level of objects that themselves implement the corresponding interfaces, but at the level of modules, then what is the implementation of the module interface?

Answer: speaking in the language of design patterns, then a special object can be responsible for the implementation of the module interface - Facade . If you're calling methods on an object that contains the Gateway suffix (for example, MobileApiGateway), then it's most likely a facade.

A facade is an interface object that accumulates a high-level set of operations for working with a certain subsystem, hiding its internal structure and true complexity behind it . Provides protection against changes in the subsystem implementation. Serves as a single entry point - "you kick the facade, and he knows who needs to be kicked in this subsystem in order to get what he needs."

You have just been introduced to one of the most important design patterns that allows you to use the concept of interfaces when designing modules and thereby loosen their coupling - "Facade".

In addition, "Facade" makes it possible to work with modules in the same way as with ordinary objects and apply all the useful principles and techniques that are used in the design of classes when designing modules.

Facade: module interface

Note : Although most programmers understand the importance of interfaces when designing classes (objects), it seems that many discover the idea of ​​using interfaces at the module level themselves.

Comments
  • Popular
  • New
  • Old
You must be signed in to leave a comment
This page doesn't have any comments yet