How to separate libraries in an app suite?

Asked

Viewed 123 times

6

I have a suite of web applications composed of several applications, each one specialized in a company area, such as property management, contract management, HR management, works management, among others. All modules access the same database, but are separate applications.

At some point, these modules use classes and entities in common, for example, the class responsible for the properties is used in the management of works and contracts, in addition to the property management itself. There are many similar situations. To solve this problem, we have created a giant library containing all the business classes and persistence that can be used by two or more modules.

With this we create another problem, because a smaller module ends up importing a gigantic library just to use two or three classes.

What kind of architecture is usually used to handle this kind of situation that I believe is common? Create several small libraries? EJB is a way out of this kind of problem?

Java 7, Struts 1.x, Hibernate 3 and Tomcat 7 usage.

2 answers

4

For each strongly related group of entities, create a package. For example, there will be a package with the property entities. There will be another package with HR entities. There is, by itself, no problem in a package depending on several others depending on several others, what happens is that this can attract other problems. The main problems are:

  • Package A depends on package B which in turn depends on package A. Cyclical dependencies are horrible things that no one deserves. The existence of a cyclic dependency may indicate that packages A and B should be one or else that there is something wrong with their archiving. Never agree to have a cyclic dependency and always try to eliminate them as soon as possible.

  • Package A depends on package B that depends on package C, but package C is a dead weight and useless for A. In this case this means that package B is swollen, and possibly in the case of splitting it into smaller packages.

What you have to keep in mind are the rules of encapsulation, low coupling and high cohesion, which are more or less the same that apply with classes.

Prefer to use a resource architecture (REST) or services (SOA) if possible. For example, in the HR database, it should only be HR that moves, because this is the system that concentrates HR business knowledge and its database is part of this knowledge. Thus, other systems that need some information from HR should invoke the HR service to do their tasks, and never access the database directly. Note that this from here is nothing more than the concept of encapsulation applied at a higher level. Accessing the database of another system is a way to violate the encapsulation of this other system. And one of the benefits of encapsulation is the control of access (and health and maintainability) of private data. At this point, your service will also be the equivalent of an interface. If you ensure that each application moves only in your database, you can prevent changes that are needed over time in a system’s database from causing side effects on other systems.

One way to reduce coupling is through interfaces that separate the specification from the implementation. This, coupled with the service or resource architecture, allows you to dramatically reduce your dependencies. Instead of relying on a class truck that changes the database of another system, you now depend only on an interface to this other system and an implementation of the type stub of this system. Stubs are nothing more than implementations of these interfaces that make the respective remote calls. If you prefer to use the EJB (not required, but an alternative), you probably won’t need to create the stubs, because EJB already takes care of it. Another simple alternative is the RMI, but I would recommend using JSON with Servlets or JAX-RS.

One way to increase cohesion is to ensure that your packages are neither too large, with features that should not belong to them nor too small, with features missing or delegated to customers. If they are too big (it might be a good idea to divide them into smaller packages). If they are too small (or to use a more precise, anemic term), then you may have separated things that should not be separated.

  • Very good answer!

2

I have worked in an environment similar to this, that is, each suite system needs to include other N systems to use its classes and entities.

Today I see this as a problem, an architectural error, a design flaw.

A given system should not include parts of other systems that are not generic or general routines to the systems. Exaggerating a little, it would be like wanting to include Google’s algorithm within my blog to do searches in my posts.

One of the biggest problems this generates is that soon you will have several versions of the systems running in different applications. Each patch on a given system will generate updates on several other systems. One might even think of some upgrade policy that works in theory, but practice will soon teach that this is not at all easy.

As Vitor Stafusa already said in the other answer, the ideal is that each system uses the services provided by the other systems on which it depends. In other words, each system made available in its own instance on the application server by accessing each other via a REST API.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.