Click here to close now.

Welcome!

Websphere Authors: Pat Romanski, Carmen Gonzalez, AppDynamics Blog, Marty Puranik, Elizabeth White

Related Topics: Java, XML, SOA & WOA, Websphere, Weblogic, AJAX & REA, Apache

Java: Article

Componentizing a Monolithic Application in Java

Using a simple homegrown component model and framework

Component-oriented development has many architectural advantages. In spite of this, many developers tend to solve problems the monolithic way on the first go. This article demonstrates how a monolithic design can be modified to achieve component-based design. During this conversion process, the necessity of Component Models and Frameworks are highlighted. The article demonstrates the componentization of an example monolithic application using a simple homegrown component model and framework developed by the authors.

Introducing E-Store - A Business Application
Let us assume that we need to implement a simple E-store business application. The application needs to cater to the following simple business use cases for a single actor - the consumer.

  • Browse the catalog of products - Consumer can browse through the items in the store. E-store app displays the different products available in the store along with their price
  • Buy one or more products - User adds one or more quantities of a product to the shopping cart. If sufficient stock is available, E-Store app adds the selected items to the shopping cart
  • Check-out - User can checkout with the items in the shopping cart. E-store app displays the total price of all the items in the shopping cart. Subsequently, stock quantities of the purchased items are reduced

Monolithic Implementation of E-Store
The E-Store application explained above can be realized with the help of the classes shown in Figure 1.

Figure 1: Class Diagram for E-Store Application

The implementation of the above design in source code and binary code form can be obtained from the links provided at the end of the article. The implementation of the monolithic application is explained briefly in the sections below.

Application Startup - UI
The monolithic E-Store application starts up with the UI class main method. During its startup, the UI class instantiates the Store (E-Store) class. The code snippet corresponding to this is shown in Listing 1.

public class UI {

static Store estore = new Store();

public static void main(String[] args) {
int userChoice = mainMenu();
...
}
...
}

Listing 1: Startup Code - UI Class

The E-Store class instantiates the Inventory and ShoppingCart classes during its startup as shown in Listing 2.

public class Store {

Inventory inventory = new Inventory();
ShoppingCart shoppingCart = new ShoppingCart();
...
}

Listing 2: Startup Code - E-Store Class

The inventory class initializes the stock during its instantiation, by creating instances of Product class objects. The code snippet is shown in Listing 3

public class Inventory {

private Map<Product, Integer> stock = new HashMap<Product, Integer>();

public Inventory() {initStock();}

private void initStock() {
Product newIPad = new Product("NewIPad", 400.00);
stock.put(newIPad, 50);

Product galaxyTab2 = new Product("GalaxyTab2", 300.00);
stock.put(galaxyTab2, 75);

Product kindleFire = new Product("KindleFire", 250.00);
stock.put(kindleFire, 30);
}
...

}

Listing 3: Startup Code - Inventory Initialization

Once the startup is done, the UI class presents a console based menu as shown in Listing 4.

Welcome to eStore!
------------------------

1. Browse Catalog
2. Buy Items
3. Check Out
4. Exit

Choose an option:
1

Listing 4: Console based UI Menu

When the user chooses any one of the options, the UI class calls upon its implementation in the E-Store business class. The implementation of each of these is explained briefly in next few sections.

Browse Catalog Use case Realization
The getCatalog() method in the E-Store class implements this use case. When the getCatalog() method in E-Store class is called, it fetches the list of products from Inventory and returns the same. Code snippet is shown in Listing 5.

public Collection<Product> getCatalog() {

return inventory.getProducts();

}

Listing 5: E-Store Class - getCatalog() implementation

Buy Items Use case Realization
The buyItem() method in the E-Store class implements this use case. The UI class calls this method by passing the name of the product chosen by the user, and the quantity he wants to buy. If sufficient quantity is available in stock, the item is added to the shopping cart and the method returns success; otherwise, the method returns failure and no item is added to shopping cart. The code snippet is presented in Listing 6.

public boolean buyItem(String name, int quantity) {
Product product = inventory.getProduct(name);
if (product == null) return false;

if (inventory.getStock(product) >= quantity) {
shoppingCart.addItem(product, quantity);
return true;
}
return false;
}

Listing 6: E-Store Class - buyItem() implementation

Check Out Use Case Realization
The checkout() method in the E-Store class implements this use case. It reduces the stock in the inventory by the quantity bought. It also returns the total price to be paid by the user. This implementation is shown in Listing 7.

public double checkOut() {
for(Product product : shoppingCart.getItems()) {
int quantity = shoppingCart.getCount(product);
inventory.reduceStock(product, quantity);
}
double price = shoppingCart.getTotalPrice();
shoppingCart.clearItems();
return price;

}

Listing 7: E-Store Class - checkOut() Implementation

What's wrong with the Monolithic implementation?
The initial implementation of E-Store discussed above fulfills all the functional requirements of the application laid down earlier. Still this is not considered as architecturally sound application design because all the classes in the application are tightly coupled to each other. Consider the dependency metrics shown in the table below:

Table 1: Class dependency details

No.

Class

Depends On

# of Dependencies

Dependency Depth

1.

Product

 

0

0

2.

Inventory

Product

1

1

3.

ShoppingCart

Product

1

1

4.

EStore

Inventory, ShoppingCart, Product

3

2

5.

UI

EStore, Product

2

3

 

 

 

 

 

The tight coupling results in high resistance to change in implementation. For example, any change to Product class will require complete change in the application.

Let us say that the E-Store likes to announce promotional sale for three days. During these three days, the total price of the shopping cart should be discounted by 10%. In order to achieve this, we need to change the ShoppingCart class implementation. When the ShoppingCart class is changed, the E-Store class also needs to be recompiled. When the E-Store class is recompiled, the UI class also needs to be recompiled.

What happens at the end of the promotional sale when the E-Store wants to discontinue the discounts? We need to recompile all the 3 classes one more time. Ideally, since the changes affect only the ShoppingCart behavior, rest of the application modules should not have been affected. But due to the tight coupling, other modules are also affected.

Loosening the Coupling through Componentization
Low coupling design principle suggests that there should not be tight coupling among unstable entities. Having dependency on a relatively stable entity does not bring forth the evils of tight coupling.

In order to make the application modules loosely coupled, we need to componentize the application. A component is a deployable piece of software that would be independently developed and independently maintained. Independence here refers to development and maintenance of a component independent of the other components which collaborate with this component in an application assembly. In a component based application, change to one component should not directly affect the application.

We avoid tight coupling between components by introducing the abstraction of Component Interface. A component interface exposes the signature of the functionalities implemented by component. The Component Interface will be a relatively stable entity as compared to the Component Implementation.

A component consumes interfaces that it depends on for fulfilling the required functionality and provides interfaces for the functionality it provides. For collaboration with the other components, the component would work through the interfaces provided by the other components. Practically, the component should not depend on the implementation of the other components; it should depend only on the interfaces provided by those components. This way, the coupling among components is through the relatively stable interfaces and not through the highly instable implementations. Thus the principle of low coupling is upheld.

In addition to the low coupling achieved, componentization of a monolithic application also brings about substitutability of components. This means a component of the application can be substituted by another component without affecting the overall application. The only requirement is that the replacing component must offer the same set of interfaces as was offered by the component being replaced.

Componentizing the E-Store Application
We need to introduce the Component Interface abstraction in the monolithic design shown in Figure 1. Looking at the dependency details represented in the Table 1, the Product, ShoppingCart, Inventory and Store classes should be represented as components. From the implementation classes of Product, Inventory, ShoppingCart, and Store, we can extract Java Interfaces IProduct, IInventory, IShoppingCart, and IStore respectively using the refactoring tools in the IDE. The extracted interfaces are shown in Figure 2. It must be noted in Figure 9 that the method signatures in IInventory, IShoppingCart, and IStore are changed to refer to IProduct interface in place of the Product class in the corresponding methods in Figure 1.

Figure 2: E-Store Interfaces - Class Diagram

In this E-Store application, there are four components represented by their interfaces - IProduct, IInventory, IShoppingCart and IStore. After the interfaces are extracted from the monolithic implementation, it will be a good design to get these interfaces packaged into a separate Java Package called estore.ifce.

The package can also be compiled to a JAR resulting in a deployable and independently maintainable estore.ifce module. This module does not implement any component, but it simply defines ONLY the interfaces which would be implemented by other components in the application. All the components depend ONLY on this common interface module and they need not depend on individual implementation components.

Following the above principle, if we separate the implementation of Product, Inventory, ShoppingCart, and Store into individual packages and into individual JARs, we get the  package structure shown in Figure 3.

Figure 3: Package Diagram separating interface from implementation

When we refactor the code into multiple components as shown above, two code segments fail to compile as shown in Figure 4 and Figure 5. Kindly look at Listings 2 and 3 for reference.

Figure 4: Compilation error in Inventory class post Componentization

Figure 5: Compilation error in Store class post Componentization

The compilation errors occurred due to the fact that above code tried to invoke the implementation code of other components directly. We have arranged our dependencies such that one component would not depend on the internal implementation of the other component. The above code violates this.

This problem can be solved in various ways. This is where all the component models and frameworks come to the rescue. Component models like RMI, EJB, Spring, OSGi and SCA have their own way of creating object references to components from the interfaces. Users can choose to use one of these frameworks or models for initializing the component. However in this article, we will look at a simple component model developed to solve this problem without using any of the component models and frameworks. This component model uses some of the principles of design pattern and best practices which is explained in detail below.

The problem of direct reference to implementation can be resolved by introducing a ‘Factory' object that can be used by the component to obtain an object of the corresponding type. A generalized Factory object could have a signature as below:

public interface IFactory<T> {
public T createInstance();

}

To avoid tight coupling, the Factory object is really useful. So, instead of coupling to a concrete class which implements IProduct, the Inventory implementation can depend on a Factory object of type IFactory<IProduct>. By invoking the createInstance() method on the factory object, the Inventory class can obtain new IProduct objects. Similarly the IInventory and IShoppingCart objects can be obtained from the respective Factory objects using createInstance() method in the Store class.

IProduct iPad = productFactory.createInstance();
.....
IShoppingCart shoppingCart = shoppingCartFactory.createInstance();
IInventory inventory = inventoryFactory.createInstance();

To obtain a factory object, a FactoryRegistry class is used as a common factory registry for registering and retrieving factory objects using the whiteboard pattern. The common registry object can be implemented as shown in Listing 8.

public class FactoryRegistry {

private static Map<Class<?>, IFactory<?>> factoryMap = new HashMap<Class<?>, IFactory<?>>();

public static void registerFactory(Class<?> ifceClazz, IFactory<?> factory) {
factoryMap.put(ifceClazz, factory);
}

public static IFactory<?> getFactory(Class<?> ifceClazz) {
return factoryMap.get(ifceClazz);
}
}

Listing 8: FactoryRegistry Class

The Inventory class can obtain a reference to a product factory object of type IFactory<IProduct> using the whiteboard pattern. Similarly any factory object can be retrieved from the FactoryRegistry.

IFactory<IProduct> productFactory =
(IFactory<IProduct>) FactoryRegistry.getFactory(IProduct.class);

One important question that remains unanswered is how, where and when these factory objects are registered with the FactoryRegistry. All component implementations only try to GET references. As mentioned earlier, component models like RMI, EJB, OSGi have their own service repository where these references are registered and components using these references look up the repository to get an object of the corresponding type. In this simple model, a registry program named ‘ComponentRunner' is handwritten which will look up for IFactory type interfaces and its implementations and register them appropriately so that getFactory method returns an initialized factory object. Kindly refer to the source code provided for details on ComponentRunner.

Implementation of this model will help in resolving the compilation issue highlighted in Figures 4 and 5. The modified code without any compilation error using the factory pattern and registry lookup is shown in Listings 9 and 10.

private void initStock() {

IFactory<IProduct> productFactory = (IFactory<IProduct>) FactoryRegistry.getFactory(IProduct.class);

IProduct iPad = productFactory.createInstance();
iPad.setName("NewIPad");
iPad.setPrice(400.00);
stock.put(iPad, 50);

IProduct gTab = productFactory.createInstance();
gTab.setName("GalaxyTab2");
gTab.setPrice(300.00);
stock.put(gTab, 75);

IProduct kindle = productFactory.createInstance();
kindle.setName("KindleFire");
kindle.setPrice(250.00);
stock.put(kindle, 30);

}

Listing 9: Modified Inventory Class without compilation error

public class Store implements IStore {

IInventory inventory;
IShoppingCart shoppingCart;

public Store() {
IFactory<IInventory> inventoryFactory = (IFactory<IInventory>) FactoryRegistry.getFactory(IInventory.class);
IFactory<IShoppingCart> shoppingCartFactory = (IFactory<IShoppingCart>) FactoryRegistry.getFactory(IShoppingCart.class);

shoppingCart = shoppingCartFactory.createInstance();
inventory = inventoryFactory.createInstance();
}
......

Listing 10: Modified E-Store Class without compilation error

Apart from the above highlighted modifications, the business logic implementation in the components remains the same as before in the monolithic case.

Executing the Sample Application
The sample application demonstrated in this article is available as a zip file for download. The zip file contains a complete Eclipse Workspace with the source as well as binary files. To run the componentized version of this application, it is required to follow the steps below:

  1. Create a folder named ‘run'.
  2. Export the components - store, product, inventory, shopping cart, component model, store app projects from the eclipse workspace to a Jar file in the ‘run' folder, say ‘eStore.jar' for example. In order to reuse these components in other applications, individual projects can be exported as separate jar files.
  3. Copy the contents of ‘bin' folder from comprunner project to the ‘run' folder. The bin folder contains a sub folder named ‘comprunner' which contains the ComponentRunner class.
  4. Open a command prompt and change the directory to ‘run' folder.
  5. To execute the ComponentRunner, type the following in command prompt

Conclusion
The advantage of a component-oriented approach is well explained with a sample application. In this article, we also saw the limitations of having a monolithic application and how the dependencies bring in tight coupling between components. Low coupling between components can be achieved by the abstraction of Component interface. Interfaces also bring in component substitutability. A component can depend on some interfaces and provide interfaces. Interface is the key mechanism in component design principles. Initialization of component implementations can happen using several mechanisms which are different for different component models and frameworks. In this sample, a home grown component model - a factory based model is used for initializing the components and component references are registered with a simple repository - CompRunner for look up.

More Stories By Piram Manickam

Piram Manickam works at Infosys Limited. He would like to acknowledge and thank Sangeetha S, a beloved colleague and friend, for her invaluable contributions in this work.

More Stories By Subrahmanya SV

Subrahmanya SV works at Infosys Limited. He would like to acknowledge and thank Sangeetha S, a beloved colleague and friend, for her invaluable contributions in this work.

More Stories By S Sangeetha

S Sangeetha is a Senior Technical Architect at the E-Commerce Research Labs at Infosys Limited. She has over 15 years of experience in architecture, design and development of enterprise Java applications. She is also involved in enhancing the technical skills of Architects at Infosys. She has co-authored a book on ‘J2EE Architecture’ and also has written numerous articles on Java for various online Java forums like JavaWorld, java.net, DevX.com and internet.com. She can be reached at sangeethas@infosys.com.

Comments (1)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


@ThingsExpo Stories
With several hundred implementations of IoT-enabled solutions in the past 12 months alone, this session will focus on experience over the art of the possible. Many can only imagine the most advanced telematics platform ever deployed, supporting millions of customers, producing tens of thousands events or GBs per trip, and hundreds of TBs per month. With the ability to support a billion sensor events per second, over 30PB of warm data for analytics, and hundreds of PBs for an data analytics archive, in his session at @ThingsExpo, Jim Kaskade, Vice President and General Manager, Big Data & Ana...
In the consumer IoT, everything is new, and the IT world of bits and bytes holds sway. But industrial and commercial realms encompass operational technology (OT) that has been around for 25 or 50 years. This grittier, pre-IP, more hands-on world has much to gain from Industrial IoT (IIoT) applications and principles. But adding sensors and wireless connectivity won’t work in environments that demand unwavering reliability and performance. In his session at @ThingsExpo, Ron Sege, CEO of Echelon, will discuss how as enterprise IT embraces other IoT-related technology trends, enterprises with i...
When it comes to the Internet of Things, hooking up will get you only so far. If you want customers to commit, you need to go beyond simply connecting products. You need to use the devices themselves to transform how you engage with every customer and how you manage the entire product lifecycle. In his session at @ThingsExpo, Sean Lorenz, Technical Product Manager for Xively at LogMeIn, will show how “product relationship management” can help you leverage your connected devices and the data they generate about customer usage and product performance to deliver extremely compelling and reliabl...
The Internet of Things (IoT) is causing data centers to become radically decentralized and atomized within a new paradigm known as “fog computing.” To support IoT applications, such as connected cars and smart grids, data centers' core functions will be decentralized out to the network's edges and endpoints (aka “fogs”). As this trend takes hold, Big Data analytics platforms will focus on high-volume log analysis (aka “logs”) and rely heavily on cognitive-computing algorithms (aka “cogs”) to make sense of it all.
One of the biggest impacts of the Internet of Things is and will continue to be on data; specifically data volume, management and usage. Companies are scrambling to adapt to this new and unpredictable data reality with legacy infrastructure that cannot handle the speed and volume of data. In his session at @ThingsExpo, Don DeLoach, CEO and president of Infobright, will discuss how companies need to rethink their data infrastructure to participate in the IoT, including: Data storage: Understanding the kinds of data: structured, unstructured, big/small? Analytics: What kinds and how responsiv...
Since 2008 and for the first time in history, more than half of humans live in urban areas, urging cities to become “smart.” Today, cities can leverage the wide availability of smartphones combined with new technologies such as Beacons or NFC to connect their urban furniture and environment to create citizen-first services that improve transportation, way-finding and information delivery. In her session at @ThingsExpo, Laetitia Gazel-Anthoine, CEO of Connecthings, will focus on successful use cases.
The Workspace-as-a-Service (WaaS) market will grow to $6.4B by 2018. In his session at 16th Cloud Expo, Seth Bostock, CEO of IndependenceIT, will begin by walking the audience through the evolution of Workspace as-a-Service, where it is now vs. where it going. To look beyond the desktop we must understand exactly what WaaS is, who the users are, and where it is going in the future. IT departments, ISVs and service providers must look to workflow and automation capabilities to adapt to growing demand and the rapidly changing workspace model.
Sensor-enabled things are becoming more commonplace, precursors to a larger and more complex framework that most consider the ultimate promise of the IoT: things connecting, interacting, sharing, storing, and over time perhaps learning and predicting based on habits, behaviors, location, preferences, purchases and more. In his session at @ThingsExpo, Tom Wesselman, Director of Communications Ecosystem Architecture at Plantronics, will examine the still nascent IoT as it is coalescing, including what it is today, what it might ultimately be, the role of wearable tech, and technology gaps stil...
Almost everyone sees the potential of Internet of Things but how can businesses truly unlock that potential. The key will be in the ability to discover business insight in the midst of an ocean of Big Data generated from billions of embedded devices via Systems of Discover. Businesses will also need to ensure that they can sustain that insight by leveraging the cloud for global reach, scale and elasticity.
The Internet of Things (IoT) promises to evolve the way the world does business; however, understanding how to apply it to your company can be a mystery. Most people struggle with understanding the potential business uses or tend to get caught up in the technology, resulting in solutions that fail to meet even minimum business goals. In his session at @ThingsExpo, Jesse Shiah, CEO / President / Co-Founder of AgilePoint Inc., showed what is needed to leverage the IoT to transform your business. He discussed opportunities and challenges ahead for the IoT from a market and technical point of vie...
IoT is still a vague buzzword for many people. In his session at @ThingsExpo, Mike Kavis, Vice President & Principal Cloud Architect at Cloud Technology Partners, discussed the business value of IoT that goes far beyond the general public's perception that IoT is all about wearables and home consumer services. He also discussed how IoT is perceived by investors and how venture capitalist access this space. Other topics discussed were barriers to success, what is new, what is old, and what the future may hold. Mike Kavis is Vice President & Principal Cloud Architect at Cloud Technology Pa...
Hadoop as a Service (as offered by handful of niche vendors now) is a cloud computing solution that makes medium and large-scale data processing accessible, easy, fast and inexpensive. In his session at Big Data Expo, Kumar Ramamurthy, Vice President and Chief Technologist, EIM & Big Data, at Virtusa, will discuss how this is achieved by eliminating the operational challenges of running Hadoop, so one can focus on business growth. The fragmented Hadoop distribution world and various PaaS solutions that provide a Hadoop flavor either make choices for customers very flexible in the name of opti...
The true value of the Internet of Things (IoT) lies not just in the data, but through the services that protect the data, perform the analysis and present findings in a usable way. With many IoT elements rooted in traditional IT components, Big Data and IoT isn’t just a play for enterprise. In fact, the IoT presents SMBs with the prospect of launching entirely new activities and exploring innovative areas. CompTIA research identifies several areas where IoT is expected to have the greatest impact.
Advanced Persistent Threats (APTs) are increasing at an unprecedented rate. The threat landscape of today is drastically different than just a few years ago. Attacks are much more organized and sophisticated. They are harder to detect and even harder to anticipate. In the foreseeable future it's going to get a whole lot harder. Everything you know today will change. Keeping up with this changing landscape is already a daunting task. Your organization needs to use the latest tools, methods and expertise to guard against those threats. But will that be enough? In the foreseeable future attacks w...
Disruptive macro trends in technology are impacting and dramatically changing the "art of the possible" relative to supply chain management practices through the innovative use of IoT, cloud, machine learning and Big Data to enable connected ecosystems of engagement. Enterprise informatics can now move beyond point solutions that merely monitor the past and implement integrated enterprise fabrics that enable end-to-end supply chain visibility to improve customer service delivery and optimize supplier management. Learn about enterprise architecture strategies for designing connected systems tha...
Dale Kim is the Director of Industry Solutions at MapR. His background includes a variety of technical and management roles at information technology companies. While his experience includes work with relational databases, much of his career pertains to non-relational data in the areas of search, content management, and NoSQL, and includes senior roles in technical marketing, sales engineering, and support engineering. Dale holds an MBA from Santa Clara University, and a BA in Computer Science from the University of California, Berkeley.
Wearable devices have come of age. The primary applications of wearables so far have been "the Quantified Self" or the tracking of one's fitness and health status. We propose the evolution of wearables into social and emotional communication devices. Our BE(tm) sensor uses light to visualize the skin conductance response. Our sensors are very inexpensive and can be massively distributed to audiences or groups of any size, in order to gauge reactions to performances, video, or any kind of presentation. In her session at @ThingsExpo, Jocelyn Scheirer, CEO & Founder of Bionolux, will discuss ho...
The cloud is now a fact of life but generating recurring revenues that are driven by solutions and services on a consumption model have been hard to implement, until now. In their session at 16th Cloud Expo, Ermanno Bonifazi, CEO & Founder of Solgenia, and Ian Khan, Global Strategic Positioning & Brand Manager at Solgenia, will discuss how a top European telco has leveraged the innovative recurring revenue generating capability of the consumption cloud to enable a unique cloud monetization model to drive results.
As organizations shift toward IT-as-a-service models, the need for managing and protecting data residing across physical, virtual, and now cloud environments grows with it. CommVault can ensure protection &E-Discovery of your data – whether in a private cloud, a Service Provider delivered public cloud, or a hybrid cloud environment – across the heterogeneous enterprise. In his session at 16th Cloud Expo, Randy De Meno, Chief Technologist - Windows Products and Microsoft Partnerships, will discuss how to cut costs, scale easily, and unleash insight with CommVault Simpana software, the only si...
Analytics is the foundation of smart data and now, with the ability to run Hadoop directly on smart storage systems like Cloudian HyperStore, enterprises will gain huge business advantages in terms of scalability, efficiency and cost savings as they move closer to realizing the potential of the Internet of Things. In his session at 16th Cloud Expo, Paul Turner, technology evangelist and CMO at Cloudian, Inc., will discuss the revolutionary notion that the storage world is transitioning from mere Big Data to smart data. He will argue that today’s hybrid cloud storage solutions, with commodity...