Decomposing A System

We will use a hypothetical business server to demonstrate how to identify services and components. After we define some services that are used in the system, we will take one of those services and define the different components needed by the service. The goal is to pass on some concepts that will help you define your system in manageable pieces.

System Analysis -- Identifying components

While it is beyond the scope of this presentation to provide a full-blown methodology, I do want to provide some pointers. We will start with the implementation oriented definition of components and services, and then provide a practical definition.

Component
A component is the combination of a work interface, and the implementation of that interface. Its use provides a looser coupling between objects, allowing the implementation to change independently of its clients.
Service
A service is a group of one or more components that provide a complete solution. Examples of a Service are protocol handlers, job schedulers, and authentication and authorization services.

While these definitions provide a starting place, they don't give the whole picture. In order to decompose a system (defined as a group of facilities that comprise a project) into the necessary parts, we advocate a top-down approach. That way you will avoid being bogged down in details before you know what the different facilities are.

Determining the Scope of Your Project

You always have to start out with a general idea of what your project is supposed to accomplish. In the commercial world, the initial statement of work accomplishes this. In the open source world, this is usually accomplished by an idea or brainstorming session. It can't be stressed enough the importance of having a high level view of the project.

Obviously, a large project will be comprised of many different services, and a small project will only have one or two. If you start to feel a bit overwhelmed, just remind yourself that a large project is really an umbrella for a bunch of smaller projects. Eventually, you will get to the point where you will be able to comprehend the big picture.

Statement of Work: Business Server

The Business Server is a hypothetical project. For the purpose of our discussion, its function is to handle sales orders, automatically bill customers, and manage the inventory control. Sales orders have to be processed as they come in, using some kind of transaction system. The server automatically bills the customers 30 days after the sales order is filled. The inventory is managed by both the server and by the current inventory counted at the factory or warehouse. The business server will be a distributed system, and each server will communicate with others via a messaging service.

Identifying the Services

Application design using Component Oriented patterns, surrounds around the Service and decomposition of each Service into smaller services. This is repeated until a natural size of low-level services are found, and a composition structure of the smaller services into each of the larger ones. Avalon Merlin has the features required to aggregate components into larger ones, and the Service Composition Model can be mapped one-to-one with Avalon Merlin's composition model, taking design, implementation and re-use to new levels.

We will use the Business Server Project to discover the services. Considering the overly broad statement of work, we can immediately begin to see some services defined in the description of the project. The list of services will be split into explicit ones (services that can immediately be derived from the statement of work) and implicit ones (services that are discovered due to similar work or as supporting the explicit services). Please note that the implementing company will develop not all of the services-some will be purchased as commercial solutions. In those cases, we will probably put a wrapper so that we still have a specific way of interacting with the commercial product. The implementing company will build the majority of the services.

Service Contract

It is important to realize that a Service Contract is more than just the Java interface. For each method in the interface, there are arguments, and there are often rules surrounding these arguments. Some arguments or return values are value objects that belongs to the Service Contract , and have rules of engagement associated with them, and the same goes for Exceptions that may be used. All these rules are part of the Service Contract and must be well-documented This is the responsibility of the design team, and the design methodology used will prescribe how this is managed. In case of no formal design methodology, we recommend that as a minimum, all the pre-requisites and rules are documented as Javadocs, as we have found that it is the easiest way to keep them up-to-date and available to the implementation developers (many IDEs have context-sensitive JavaDoc pop-ups).

Explicit Services

We can quickly derive a number of services from the statement of work. Our work is not done after this initial analysis, because the definition of some services requires the existence of other services.

Transaction Processing Service

The statement of work specifies that "Sales orders have to be processed as they come in". This means we need to have a mechanism of receiving sales requests and automatically process them. This is similar to the way web servers work. They receive a request for a resource, process it, and return a result (e.g. the HTML page). This is known as Transaction Processing.

To be fair, there are different types of transactions. The generic transaction service will most likely have to be broken down into something more specific like a "Sales Order Processor". The approach has to do with how generic you make your service. There is a balance between usability and reusability. The more generic a service is, the more reusable it is. Usually it is also more difficult to comprehend.

Scheduling Service

There are a couple of instances where an event must be scheduled for a specified amount of time after a transaction. In addition, the inventory control processes need to kick off supply orders on a periodic basis. Because the statement of work states "server automatically bills the customers 30 days after the sales order is filled" we need a scheduling service. The good news is that Avalon Cornerstone (obsolete - check if it has been migrated to Avalon Components) provides one for us so we don't have to create our own.

Messaging Service

The statement of work specifies that "each server will communicate via a messaging service" in our distributed system. Let's face it, sometimes customers want a specific product or method they want to use. The messaging service is a prime example of using another company's product. Most likely, we would use Java Messaging Service (JMS) to interface with the Messaging Service. Since JMS is a standard, it is unlikely that the interface will change any time soon.

In practical experience, a well-designed message oriented system will scale better than object oriented systems (like EJB). One reason for better scalability is that messaging tends to have lower concurrent overhead memory. Another reason for this is that it is easier to spread the load of message processing across all servers instead of concentrating all the processing in a small cluster of servers (or even just one server).

Inventory Control Service

While this is not a classic server piece in textbooks, it is a requirement of this system. The inventory control service routinely monitors the records for what the factory or warehouse has in stock, and triggers events when stock starts running out.

Implied Services

Using experience with past systems, and further breaking down other services will yield a number of services that the system needs that wasn't specified. Due to space limitations, we will avoid doing a full decomposition.

Authentication and Authorization Service

The authentication and authorization service is not necessarily specified in the statement of work -- but all business systems must take security seriously. That means all clients of the system must be authenticated, and every action of the user must be authorized.

Workflow Automation Service

Workflow automation is a hot development area in enterprise systems. If you don't use a third party workflow management server, you will have to invent your own. Workflow automation is generally the act of using a software system to route tasks through a Company's business process. For more information, view the Workflow Management Council's web page at http://www.wfmc.org .

Document Repository Service

This definition of a "document repository" is very loosely defined as the current state of information in a task. In other words, when the company receives a purchase order, our system needs to store and recall the purchase order information. The same goes for billing and any other process in the system from inventory to new customer requests.

Summary

I hope that the examples of services for the Business Server project will help you discover more. You will find that as you go from higher levels of abstraction down to lower levels, you will find more types of services required like Connection Management to handle requests on open ports. Some of the services we defined will be implemented by third party systems such as the Messaging Service and the Workflow Management Service. It is in your best interest to use a standard interface for these services so that you can change vendors later. Some services are actually multiple services acting as one larger service. Some are already available within Avalon Components.

One thing to keep in mind while discovering the services in a system is that a service should be a high level sub-system. This will help you define components using teams of analysts. Because we have already identified the main services, you can have more than one person (or team) decompose each of the services in parallel. The boundaries are well defined, so there is little chance for overlap. If you decide to do the parallel analysis, you should come back together to identify common components so that you can reuse as much code as possible.

Implementing the Services

Decomposition of a system is very much a design exercise, and once the Service Contract is identified, it is a fairly straight-forward process of implementing the Service into a component. It is during the component implementation that the Avalon specific patterns starts taking center stage.

Component sizes

If the system is over-designed, it will show up as too small components. Components should be bigger than JavaBeans, but not as large as commercial APIs (JavaMail for instance). After a while, it will become natural to see if things are "just right" or not. It is also important to recognize that the implementation must not, and probably should not, be inside a single class. Experience shows that it often makes sense to use several support classes, workers, value objects and so on to implement the Service Contract .

One component per Service

Although Avalon Merlin supports that a single component can implement more than one service, we only recommend that for components that wraps third-party subsystems and APIs, where it is not possible to break the thrid-party piece into multiple Avalon components. Keep One Service in One Component , it will increase re-usability later, and have few downsides.

Data are not components

People who are used to JavaBeans tend to treat everything as components, event when it clearly is not. Value Objects, data if you like, is NOT components. A more tricky example is a Network Connection, which is NOT a component. The Connection Manager is the component and it can provide Connection objects, which are more like value objects than components.

Components implements Services!

Decomposing the Document Repository Service

Back to our Business Server. We will list the Services that we are going to implement.

DocumentRepository

The DocumentRepository is our method of getting Document objects from persistent storage. It interacts with the other components in the service to provide security, functionality, and speed. This particular DocumentRepository will connect to a database and employ the logic to build the Document objects internally.

The DocumentRepository will end being an Aggregated Component from various smaller components.

DocumentStore

The DocumentStore is the main persistence handler in the repository. It is this component that implements the external DocumentRepository interface, as an Aggregated Component can not implement any code by itself.

DataSourceComponent

The DataSourceComponent is a manager of database connections. It is our method of retrieving valid JDBC Connection objects for our use.

Cache

The Cache is a short-term memory-based storage facility. The DocumentRepository will use it to store Document objects referenced by a hash algorithm. In order to promote the reusability of the Cache component, the stored object must implement a Cacheable interface.

Guardian

The Guardian component is used to manage permissions based on the Principal. The Guardian will load its permission sets from a database. The Guardian will use the standard Java security model to enforce access to the specific Document objects.

Summary

At this point, you should have an idea of how to break a large application into smaller pieces, and then continuing to break those pieces down to managable entities. And for each such piece, you set out to define the Service interfaces and the surrounding semantic contracts, all before needing to look at component implementations. In larger organizations, it will be possible to achieve a high level of parallelism both in Service design as well as in component implementations.

You will also know that a component should not be too small, and not too large. The component should only have one concern. Over time you will become an expert in component re-use, and as more libraries of components becomes available, your productivity will soar. You will be well set to adopt to market requirements, by easily exchange old and add new implementations of well-known domain services, with little impact on the rest of the system.