How to separate libraries into an application suite?

6

I have a suite of web applications composed of several applications, each specialized in an area of the company, 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 common classes and entities, for example, the class responsible for properties is used in works management and contract management, as well as property management itself. There are numerous similar situations. To solve this problem, we have created a giant library containing all business and persistence classes that can be used by two or more modules.

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

What kind of architecture is commonly used to handle this kind of situation that, I believe, is common? Create multiple small libraries? Is EJB an outlet for this kind of problem?

Use java 7, struts 1.x, hibernate 3, and tomcat 7.

    
asked by anonymous 16.04.2015 / 17:07

2 answers

4

For each strongly associated group of entities, create a package. For example, there will be a package with the property entities. There will be another package with the HR entities. There is no single problem in a package depending on several others that depend 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. Cyclic dependencies are horrible things that no one deserves. The existence of a cyclic dependency may indicate that packets A and B should be one or that there is something wrong in their architecture. Never accept having a cyclical 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 it means that package B is bloated, and possibly it is the case of dividing in 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 as those that apply with classes.

Prefer to use a resource architecture (REST) or services (SOA) if possible. For example, in the HR database, the mover should be just HR, as 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 jobs, and never access the database directly. Note that this is nothing more than the encapsulation concept applied at a higher level. Accessing the database from another system is a way of violating the encapsulation of this other system. And one of the benefits of encapsulation is the control of access (and sanity and maintainability) of private data. At this point, your service will also be the equivalent of an interface. If you make sure that each application only messes with your database, you can prevent any changes that are required over time in a system's database from causing side effects on other systems.

One way to reduce the coupling is by interfaces that separate the implementation specification. This, coupled with the services or features architecture, allows you to drastically reduce your dependencies. Instead of depending on a class truck that changes the database of another system, you only depend on an interface for this other system and a stub implementation of this system. Stubs are nothing more than implementations of these interfaces that make their remote calls. If you prefer to use EJB (it is not necessary, but it is an alternative), you probably will not need to create stubs , as EJB already takes care of it. Another simple alternative is RMI, but I would recommend using JSON with Servlets or JAX-RS.

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

    
16.04.2015 / 18:06
2

I've worked in a similar environment, that is, each system in the suite 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 particular system should not include parts of other systems that are not generic or general routines for systems. Exaggerating a bit, it would be like wanting to include the Google algorithm inside my blog to do research on my posts.

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

As Vitor Stafusa has 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 accessing each other via a REST API.

    
20.04.2015 / 20:14