This article is intended to experienced Java EE developers who desire to become the Architects of Enterprise applications in Java. It is also useful to the developers, designers, architects who want to create effective blueprints of applications. The title “How to Design a Java Enterprise Application Effectively?” will cover a lot of new demands with faster delivery in an enterprise application as moving fast is one of the most important criteria of today’s IT companies.
Moreover, we will discuss some best practices to design an enterprise application that suits the current demands. We will also cover the design comparison of Monolith with Microservices based application.
Motivation to adapt Design as per Modern Applications
Adapting design as per modern applications is all about quickly adapting to the needs of the current market and customers. If a new feature is desired or looks promising by the customer, how fast we can deliver it to the customer? What are all possibilities to adapt modern tools, technologies, frameworks etc. so that there is automated quality control in place that ensures everything will work as expected. Also, what are the solutions we are going to provide in the design so that it does not break the existing functionality of an already developed application?
In Modern software development, reliability, automation, continuous delivery, robustness, portability, minimal maintenance are some of the most important principles. These are preconditions to hand over a good software design. A reliable, automated process not only gives on to speedy delivery, but sooner or later a higher quality as well. Let’s learn how to Design a Java Enterprise Application Effectively step by step.
Prerequisite before creating an Application Design
Before creating a design of application, we should know the purpose of the application that we want to develop. The motivations and purposes of the enterprise systems need to be crystal clear before going into technology details. Otherwise, the software is just being developed for the sake of developing functionalities. We should ensure that the software to be built will achieve the business needs. Here, we will discuss the whole process of designing the application step by step. The sequence of steps may differ. Below is the summary of steps that we will cover in detail in this article.
1) Knowing the purpose of the application
2) Designing Application Structure
3) Finalizing Technology & Framework
4) Choosing Front-end Technology
5) Structuring Layers of the Application
6) Designing Business-driven Modules
7) Designing the Packages & Sub-Packages
8) Packaging the classes (Binaries)
9) Finalizing the Build Tools
10) Deciding the Version Control System
Knowing the complete purpose of the Application
Before developing a software application we should ask ourself some questions:
1) Why to develop this Application?
2) What is the purpose of application?
3) What is the problem that this software is going to solve?
4) Would it return some revenue? If yes, directly by selling the application or indirectly by supporting or providing services to customers?
5) Why does it require to spend time and effort to develop a solution?
Every application needs genuine answers to these questions before we spend time and effort into it.
Designing Application Structure
In Monolithic Java projects, We can bundle the components & responsibilities into a certain structure called Java Packages and Project Modules respectively. Structuring the application in this way is necessary to deliver a good application architecture. It helps developers understanding the application and its responsibilities quickly. By grouping the coherent components that form logical features into logical packages or project modules, we can increase cohesion and accomplish a better management of the source code. Java SE 9 introduces the grouping of components as modules also known as Java 9 modules. These modules are similar to the JAR files with the facility to declare dependencies on other modules with usage restrictions. The smallest unit of a Java Application is a Java class. Ideally, we should keep classes loosely coupled and highly cohesive.
In Microservices based Java Projects, we consider a module as a single microservice or application. We should follow the same package structure as it is in a Monolithic application.
Single vs Multi-module Projects- Monolithic Architecture
For small applications Single module is justifiable whereas for a big application such as enterprise application, it is advisable to go with multi-module design. The more complex our software project becomes the longer. It will take to compile and package it into artifacts, so it will directly impact build-time performance. Using multi-module practice, we will have the possibility of reusing certain sub-modules in other projects. eg. a general practice is to design a common utility module that contains several helper classes. We can package this module as a JAR file and re-use as a dependency in other projects. One important point here to note is that shared modules should be as less dependent as possible or at least contain only stable dependencies.
Benefits of Using Microservices Architecture
Rather than using Monolith architecture, if we use Microservices Architecture, we don’t need to do much exercise on deciding modules & their dependencies. Each module will compile in less time and even provide the best build-time performance. Additionally, it provides the easy reusability of other modules.
Finalizing Technology & Framework
Once the application’s purpose and functionality is clear to all the stakeholders, we can keep our focus on the technological aspects. We should favor technologies that can implement the business use cases fairly and also minimize the amount of work and overhead. Developers should be able to focus on the business use cases, but not on the framework and technology. A Designer should choose the frameworks that can support solving business problems intelligently. We should choose the technology that can also support rich development workflows as much as possible. This not only incorporates automation and speedy development turnarounds, but also the ability to accept modern infrastructure, such as Linux boxes. Decision of Technology & Framework can be the turning point in how to Design a Java Enterprise Application Effectively.
Now-a-days, Spring Boot is the most popular among Java developers & projects. It is suitable in Monolithic as well as Microservices based projects.
Choosing Front-end Technology
Although It doesn’t matter which specific front-end technology is chosen, enterprise projects now have more advanced front-ends than in the past. However, It is always a recommendation that separate the front-end into a dedicated project module. The reason is that the front-end may have different life cycles than the rest of other modules and we can ship it individually.
If we have planned deployment of front-end with back-end as a single unit, we require more coordination between teams. On the other hand, this integration isn’t undoubtedly helpful during development if the cycles of developing the front-end differs from the back-end. A developer currently working on the front-end side may not want to build the back-end part each and every time.
Moreover, It is also a recommendation to package the front-end module as an independent module and to introduce it as a dependency of the back-end module. By doing so, we can build the front-end module separately, whereas a back-end developer can rebuild the back-end part as well by using their latest version of the front-end. Therefore, we can reduce the time taken in the build process on both the sides. Angular & React is becoming more popular & demanding in the market day by day, so we can consider them the best options for a Java application. Also, they are the well qualified and suitable front-end technologies for a java developer.
In Microservices based applications, front-end is always kept independent from the back-end. The most common way to call back-end services by Front-end is using the REST calls.
Structuring Layers of the Application
The structure of standard Java Enterprise Application is usually a three-tier architecture. It technically means three inspired layers: Presentation, Business and Data Layer. The primary idea of layering the architecture is to separate concerns from the data layer, from the business layer, and both of them from the presentation layers, as well. Each technically inspired layer or module has its own internal dependencies, that should not be used from the other layers. For example, only the data layer should be able to use the database, business layer should not invoke the database directly. Also, in future if database technology changes(Suppose from SQL server to PostgreSql), there should not be any negative impact on other layers. Similarly, if presentation technology changes, there should not be any negative impact on other layers.
Designing Business-driven Modules
The first thing that we must focus on is business needs & concerns. We should reflect these aspects in the project and module structure as well. Our domain should clearly be reflected in the application structure. Just by looking at the hierarchy of package names should give a clear idea of what the application is trying to do. Therefore, incorporating the business needs & concerns first and other implementation details second is the best approach to start with the modules design. For example, an E-commerce application should incorporate modules for users, articles, payments, orders, shipping etc. Therefore, we should consider them as the base domain modules. We should also represent them as the base Java packages in our application.
Needless to mention, in Microservices based application, each module will work as a separate application.
Designing the Packages & Sub-Packages
Suppose we are going to define packages for our Users module. In the users package we can have sub-packages such as controller, core, model, data and so on. By following this perspective, we can break up responsibilities inside the users package by their technical groupings. Also, all the other modules and packages in the project should have similar sub-packages, depending on their contents. We should assign one of the sub-packages to be the technical entry point, let’s say controller. This package should contain the communication endpoints launching the use case logic and represent as entry point outside of the application. These are applicable for Microservices based application as well.
Packaging the classes (Binaries)
The binaries are eventually the end results of the development and build process. Only these binaries can be executed as an application. So, a Java application will have to be deployed as some kind of binary artifacts. Conventionally, we package the Java source code in the form of JAR, WAR, or EAR files. These files stand for Java Archive, Web Application Archive & Enterprise Application Archive respectively. Moreover, these files contain all classes and files required to ship an application, framework dependency, or library. The Java Virtual Machine (JVM) in the end will execute the bytecode (.class files) from the archives. As per the complexity of the application, we should decide which archive file needs to be created for packaging the application.
No doubt, Microservices based application saves the time in packaging the classes as they are small in size. But, here we will more than one JARs/WARs.
Finalizing Build Tools
We make changes in our java source files multiple times during the development. Therefore, it is necessary to have a software which can make our code compilation process as fast as possible. The primary responsibility of the build tool is to compile java source file into bytecode(.class file). Apart from that, build tools help us to recognize all the sub-module dependencies. It also helps us in packaging all compiled classes and their dependencies into a deployment artifacts. These artifacts are packaged as JAR,WAR or EAR depending on the nature of the application. Apache Maven & Gradle are the most powerful tools in this category in modern days and Maven is the most popular among the majority of java developers. Apache Ant is out of date now.
Deciding the Version Control System
We have a lot of options for version control systems, such as Git, Subversion(SVN), Mercurial or CVS. Now-a days CVS & SVN are rarely used. The distributed revision control system, specially Git, has extensively accepted as the modern tools in the last many years. All software projects need coordination of concurrent code changes, made by different developers. Hence Version control systems become mandatory to coordinate, track, and follow the changes in software systems.
This is all about how to Design a Java Enterprise Application Effectively. We should design a Java Enterprise application with the priority to resolve business complications rather than to technology-driven solutions. The business use cases are what in the long run will generate profits for the company. If the number of classes per module is small, we can design a module as a single Java package module. For more complex modules, it is advisable to add another hierarchical layer using patterns.
If you are interested to learn Design patterns, kindly visit our article on “Java Design Patterns“