How Would You Build Up a City from Components?

A note to our readers: As per your request we have developed a set of features that allow you to reduce the noise, while not losing sight of anything that is important. Get email and web notifications by choosing the topics you are interested in.

More and more enterprise application development is moving to component frameworks and solutions. Why? Does component architecture have any future? I believe yes and soon all development frameworks will be component-based - it is imminent. Let me show you why.

How do you build up your house? You start with building blocks. It is possible to compare the construction of a web application with the construction of your small country house. You can quickly build up a very good looking application with all the required functionality. Every room in your house is created for specific needs, for instance the kitchen, living room, bedroom or bathroom. The layout of the house allows you to conveniently move between rooms using the corridors and stairs.

You are doing better now and can afford to build a bigger and better house – you would like to have a sauna, a pool, a movie theater and of course a giant aquarium filled with reptiles☺. But changing the design of your house can be quite difficult. If you are able to add the extra facilities the house ends up not looking so nice. It is also less convenient since your additions had to be put in inconvenient places, so that, for instance, to get into the billiard room you have to pass through the main bedroom.

In the end your nice and neat house turns into an awkward and uncomfortable house with a bunch of different functions within it. The same story can happen with application development.

The question is, is it possible to design an application such that it can grow and change according to your needs? Let’s try to figure it out.

Components are building blocks of the application

Components are the primary means of extending application functionality. The process of creating components is a bit different from the creation of applications based on them. The component should not only provide useful functionality but be designed for reuse from the outset.

Reuse of components

To easily reuse components they should be designed with a loose coupling approach. To make this possible, different frameworks typically implement their event models based on the Observer pattern. This allows multiple recipients to subscribe to the same event.

The Observer pattern was originally implemented in Smalltalk. Smalltalk is a user interface framework based on MVC and is now a key part of MVC frameworks. I would like to draw your attention to the fact that the Observer pattern has existed in Java since version 1.0. Let’s have a deeper look into it.

Firstly we create an instance of ObservableX class, add the ObserverA and ObserverB instances into the observableX object and then somewhere in the code we set the value for "some amount" using the setAmount method. The functionality of the observable class notifies all the registered observers about the received amount.

The Observer acts as a mediator that maintains the list of recipients. When some event occurs within a component it is sent to all recipients from that list.

Due to the mediator the component isn’t aware of its recipients. And the recipients can subscribe to the events of different components of a particular type.

A class can become a component when it uses events to notify observers about its changes. And this can be achieved by using the Observer pattern.

To use components is easier than to create them

Using components you can quickly create a variety of forms, panels, windows, and other composite elements of the interface. However, to be able to re-use the new composite parts they should be turned into components.

In order to achieve this you do need to determine the external events that the component will generate as well as the mechanism of sending messages. I.e. you need to at least create new event classes and define interfaces or callback methods for receiving those events.

This approach makes the implementation of reusable application components more complex. It is fine if the system consists of a small number of composite elements - up to around ten. But what if the system consists of hundreds of such elements?

Conversely, not following this approach will lead to tight coupling between elements and will reduce the chances of re-use to zero. This, in its turn will lead to code duplication that will make maintenance more complicated in future and will lead to a growing number of bugs in the system.

The problem is compounded by the fact that users of the components often do not know how to define and send new events to their parts. But they can easily use ready-made events provided by the component framework. They know how to receive events but don’t know how to send them.

To solve this problem, let's consider how to simplify the use of the event model in applications.

Too many Event Listeners

In Java Swing, GWT, JSF and Vaadin the Observer pattern is used for implementation of an event model where multiple users can subscribe to one event. Lists to which Event Listeners are added serve as the implementation. When the relevant event occurs it is sent to all the recipients of that list.

Each component creates its own set of Event Listeners for one or more events. This leads to an increasing number of classes in the application. That, in its turn, makes support and development of the system more complicated.

With annotations Java gained a way to have individual methods subscribe to particular events. As an example consider the implementation of the event model in CDI (Contexts and Dependency Injection) from Java EE 6.

The EventBus registers the object of the EventBusChangeRecorder class. Then calling the changeCustomer() method results in the EventBus receiving the ChangeEvent object and calling the recordCustomerChange () method of the EventBusChangeRecorder object.

Now you don’t need to implement a number of Event Listeners for your components, making the use of events in applications simpler.

The Event Bus usage is convenient when all the components are displayed at the same time on the screen and they use the Event Bus for message exchange, as shown in the picture below.

Here all these elements - the header, left menu, content, right panel - are components.

Subscribed to events – don’t forget to unsubscribe

By replacing Event Listeners with annotations we have made a big step forward in simplifying the use of the event model. But even so, every component in the system needs to be connected with the Event Bus, and then has to subscribe events to it and, at the right time, unsubscribe from it.

It is possible to hit a situation when the same recipient is subscribed several times to the same event, which can lead to a number of repeated notifications. A similar situation can arise when multiple system components subscribe to the same event, which can trigger a series of cascade events.

To be able to control the event model better, it makes sense to move the work with events out to configuration and make the application container responsible for events management. Since particular events are available only on particular conditions, it is reasonable to move the management of their state out to configuration as well.

The transition to the B view will be initiated by the “next” event from the A view. From the B view the user can go back to the A view by the “previous” event or to the C view by the “next” event. From the D view the finish event leads to the “final” state which instructs the application to finish up the workflow within the application.

Finite State Machines are specifically designed for such needs. A state machine is a mathematical model of computation. It is conceived as an abstract machine that can be in one of a finite number of states, but only in one state at a time, known as the current state. An event or condition can trigger a transition to another state. Using this approach you can easily define an active screen and have an event trigger a transition to another screen.

The benefits of using Finite State Machines for configuring the application

In most cases application configuration is defined statically. Configuring the application with dependency injection we define application structure on startup. But we forget that while exploring the application its status can change. Change of state is often hard-coded in the application code which leads to complications in future adjustments and maintenance.

Moving the transitions between states into configuration gives more flexibility. And that’s why when creating composite application elements, such as forms, windows or panels, we don’t need to worry about what state the application should go to. You can do this later, setting the behavior in the configuration.

All the components can communicate using a standardized mechanism for sending events - through the Event Bus. At the same time, the state machine can control the subscription of component events to the Event Bus. This approach turns all components of the application (forms, windows, panels) into reusable components that can be easily managed from the external configuration.

If you are interested you can have a look at some examples of configuration in the Enterprise Sampler.

You can consider state configuration as a road map of a city, and events as cars delivering goods and people to the desired destinations.

I'm sure using this approach it is easy to design and build up not just a small and ready to grow house but a whole city with skyscrapers, broadways and highways.

About the Author

Aliaksei Papou is CTO, Software Architect and Co-founder of Lexaden.com. He has more than 10 years experience in the development of enterprise applications. The innovation of technologies is his passion. Aliaksei and Denis Skarbichev, CEO and Co-founder of Lexaden.com, have developed the Lexaden Web Flow language that allows the creation of large scale agile enterprise applications.

Is your profile up-to-date? Please take a moment to review and update.

Email Address

Note: If updating/changing your email, a validation request will be sent

Company name:

Keep current company name

Update Company name to:

Company role:

Keep current company role

Update company role to:

Company size:

Keep current company Size

Update company size to:

Country/Zone:

Keep current country/zone

Update country/zone to:

State/Province/Region:

Keep current state/province/region

Update state/province/region to:

Subscribe to our newsletter?

Subscribe to our architect newsletter?

Subscribe to our industry email notices?

You will be sent an email to validate the new email address. This pop-up will close itself in a few moments.

We notice you're using an ad blocker

We understand why you use ad blockers. However to keep InfoQ free we need your support. InfoQ will not provide your data to third parties without individual opt-in consent. We only work with advertisers relevant to our readers. Please consider whitelisting us.