Design Modeling in J2EE Applications
Topics in This Chapter
-
Creating a Design Model
-
Design Guidelines
-
Mapping a Domain Model to a Design Model
-
Designing Data Access Objects, Transfer Objects, and Business Rule Objects
In designing a complex J2EE business application, a design model is a necessity.
A design model is a detailed specification of the objects and relationships within an application, as well as its behavior. To understand the requirements originating from the business and to preserve the ability to trace these requirements to the application's implementation and back, it is clearly beneficial to keep the design model and domain model in sync. This chapter describes how to derive a design model from a common domain model, preserving this needed synchronization.
Also included in this chapter are guidelines for designing the integration tier of a multi-tiered J2EE application intended to integrate with legacy systems and other data sources. These guidelines are presented in terms and concepts associated with design models as presented in this chapter. Design patterns such as Transfer Objects and Data Access Objects [Core J2EE Patterns, D. Alur, J.Crupi, D. Malks, Prentice-Hall 2001] are used as the building blocks from which the integration tier is designed.1
2.1 Creating a Design Model
A design model is an object model that describes the realization of use cases, and it serves as an abstraction of the implementation model and its source code [The Unified Software Development Process, I. Jacobsson, G. Booch, J. Rumbaugh, Addison-Wesley 1999]. A design model consists of the following artifacts:
-
A class diagram: This diagram contains the implementation view of the entities in the domain model. Each object in the design model should, ideally, be exactly traceable to one or more entities in the domain model. This property ensures that the requirements, as specified in use cases containing entities defined in the domain model, are realized by corresponding classes in the design model. The design model also contains non-core business classes such as persistent storage and security management classes.
-
Use case realizations: Use case realizations are described in collaboration diagrams that use the class diagram to identify the objects that participate in the collaboration diagrams.
If the class diagram of the design model is created as a derivative of the class diagram of a domain model, each class in the design model traces to a corresponding class in the domain model. There can be one-to-one, one-to-many, and many-to-many relationships between design classes and domain classes.
Because it should be possible to implement a domain model in more than one way, the direction of this class tracing should normally be only from the design model to the domain model. Furthermore, keeping the domain model consistent with updates in the derived design models is impractical.
The traceability of a design model to the domain model aids IT architects and application designers by providing a realization of the use cases that closely corresponds to the business entities defined in the domain model. In other words, there is no confusion over domain model entities used to describe business use cases, since their corresponding design classes also exist in the design model.
Mapping a Domain Model to a Design Model
An entity defined in the domain model is represented as a Transfer Object and a Data Access Object in the design model (see Figure 2.1).
Figure 2.1. The realization of an entity class
For each domain model class having the stereotype <<entity>>, the design model contains a corresponding Transfer Object and possibly also a Data Access Object. Each domain model class having the stereotype <<utility>> is mapped to a Supporting Object class in the design model. Classes stereotyped <<type>> are mapped to enumerated type classes.
The design model class diagram consists of UML interfaces, classes, and associations. The following sections describe in detail procedures by which entities and relations in a domain model are mapped to elements in a design model. Note that the procedures apply to both the common domain model and application-specific domain models.
Entities
Each domain model class having stereotype <<entity>> is mapped to a corresponding interface in the design model having stereotype <<Transfer Object>>. Each attribute of this class is mapped to public get<AttributeName> and set<AttributeName> methods in the corresponding interface.
Types
As previously stated, a domain model class having stereotype <<type>> should always inherit from a base class that names the entity to which the type belongs. In the design model, this is represented by a class having stereotype <<Supporting Object>> with the class name <Entity>Type (the name of the base entity followed by the word Type). The subclasses having stereotype <<type>> are then mapped to constant attributes in the Supporting Object class.
Figure 2.2 shows an example in which different Product types are mapped to the Supporting Object class ProductType, which contains the constant object attributes INFORMATION_PRODUCT and FINANCIAL_PRODUCT.
Figure 2.2. The ProductType class
When a type has subtypes, the type and subtypes should be collapsed into a flat structure of values.
The Transfer Object interface representing the base entity in the domain model should have both a get<Entity>Type method and a set<Entity>Type method in the interface definition, where the get method returns one of the constant objects of the <Entity>Type class, and the set method takes a constant object of the <Entity>Type class as in-parameter.
Utilities
In the design model, a domain model utility is represented as a class having stereotype <<Supporting Object>>.
Associations
In the design model, an association between two domain model entities is mapped to a get<AssociationName> method and a set<AssociationName> method in the Transfer Object Interfaces corresponding to the domain model entities. For example, a Party having the association CustomerRole to a Customer would be represented as a class Party having getCustomerRole and setCustomerRole methods. Similarly, the Customer class would be designed to have getPartyRole and setPartyRole methods.
To avoid retrieving too much data when reading a Transfer Object from persistent store, associations between entities can be represented with identifiers rather than with direct object references to Transfer Objects. (This concept is discussed in greater detail later in this chapter.) With this method, there is no type information directly available from an association. When implementing the application from the design model, therefore, the domain model must be used to indicate from which Data Access Object a referenced Transfer Object should be retrieved.
Another option is to create Business Rule Objects that, based on a Transfer Object and an association name, return the Data Access Objects that then retrieve the correct Transfer Object instances.
Association Classes
Some associations consist of an association class. Depending on whether or not the association class has an identifier, it can be represented in the design model as either a Transfer Object interface or a Supporting Object class. A one-to-many association between two entities consisting of an association class could be mapped in two ways:
-
As a one-to-one association between the first Transfer Object and the association class, which contains a one-to-many association to the second Transfer Object
-
As a one-to-many association between the first Transfer Object and the association class, which contains a one-to-one association to the second Transfer Object
The following guideline is helpful in choosing one of these approaches: If the association class represents membership in a group, the first type of mapping should be used; otherwise the second mapping should be used. The following examples illustrate this concept:
-
Example 1: A Party has a colleague role to many other Parties. Since these all work for the same employer, the colleague role is represented through an Employer class having its own identifier and name and so on. Each Party has a one-to-tone relationship with the Employer class, while the Employer class has a one-to-many relationship with the Party class.
-
Example 2: A Party has a supplier role to many other Parties. The Parties, representing customers in this case, each have a unique customer ID in the supplier's own records. That is, this ID is not part of the Party definition but a property of the association class Customer. Since the customers in this case are not members of a group. The relationships between the Party having the supplier role and the Parties having the customer role are represented with a number of one-to-many associations from the Party class to the Customer class, as well as with a one-to-one association from Customer class to the Party class.
Summary of Guidelines
Table 2.1 summarizes guidelines that should be used in creating a design model class diagram from a domain model:
Table 2.1. Mapping guidelines
Domain model element |
Design model representation |
Stereotype |
Restrictions |
Comment |
---|---|---|---|---|
Entity |
Interface |
<<Value Object>> |
Must have a unique identifier Must be associated with a Data Access Object |
|
Type |
Class |
<<Supporting Object>> |
Types are mapped to constants |
Add get<Entity>Type and set<Entity>Type to Transfer Object interface |
Association |
Association, possibly aggregate |
none |
||
Association Class |
Interface |
<<Value Object>> |
Must have a unique identifier Must be associated with a Data Access Object |
Entity one-to-one to Association Class and one-to-many to Entity or Entity one-to-many to Association Class and one-to-one to Entity |
Association Class |
Class |
<<Supporting Object>> |
Must not have a unique identifier |
Entity one-to-one to Association Class and one-to-many to Entity or Entity one-to-many to Association Class and one-to-one to Entity |
Utility |
Class |
<<Supporting Object>> |
Design Model Mapping Example
Figure 2.3 shows an example of a domain to design model mapping
Figure 2.3. An Entity to Transfer Object mapping
Additional Design Model Classes
Once the straight mapping from domain model to design model has been performed, some additional design model classes need to be added.
Composite Transfer Objects
A Composite Transfer Object is a representation of an association between two or more Transfer Objects. Because associations between entities can be represented with identifiers rather than with direct object references to Transfer Objects, a separate object for maintaining these associations is needed. This object is represented in the class diagram as a class having the stereotype <<Composite Transfer Object>>. By designing relationships through Composite Transfer Objects, an application designer is free to implement only those associations needed by the application, thus avoiding unnecessary object instantiations and possibly circular references. Guidelines for designing Composite Transfer Objects are discussed later in this chapter.
Transfer Object Classes
Each Transfer Object interface that is not extended by another Transfer Object interface is complemented by a Transfer Object class that implements the Transfer Object interface and all of its extended interfaces. The implementation class should have the name <ValueObjectName>Impl and be stereotyped <<Transfer Object>>. In addition, the following properties should be applied to Transfer Objects:
-
A Transfer Object should represent data retrieved from one or more records obtained from one or more data sources.
-
Each Transfer Object must have a primary key (although there may be more than one key) that identifies the record in the data source.
-
Transfer Objects should not contain other Transfer Objects.
-
Transfer Objects must never contain or reference Composite Transfer Objects; instead, whenever possible, Transfer Objects should reference other Transfer Objects using their primary keys.
-
Transfer Objects should have no advanced business logic; this rule promotes reuse and simplifies the architecture. In particular, because Transfer Objects often are transported from one tier to another, logic related to communication with other parts of the system should be avoided.
-
It should be possible to export Transfer Objects to XML format.
-
Transfer Objects should be designed as JavaBeans™, providing a get method and set method for each attribute.
Supporting Objects
Supporting Objects constitute attributes in Transfer Objects. A Supporting Object is usually persistent but has no primary key. A Supporting Object must never contain or have a reference to a Transfer Object or a Composite Transfer Object. Supporting Objects should be implemented as a class stereotyped <<Supporting Object>>.
Business Rule Objects
The rules found in the business rule catalog of the common domain model can be represented in the design model as interfaces having stereotype <<Business Rule>>. These objects can, for example, verify the contents of a Transfer Object or of a Supporting Object. They can also be used to perform calculations based on the attribute values of a Value Object or Supporting Object. In order to be portable and reusable, a Business Rule Object must not have any side effects, such as manipulating the attribute values of a Value Object or Supporting Object. Furthermore, a Business Rule Object must not invoke methods on remote objects or communicate with external resources such as databases. Guidelines for designing Business Rule Objects are discussed later in this chapter.
Data Access Objects
For each Transfer Object class, there should be a corresponding Data Access Object interface, with the name <ValueObjectName>DAO and having the stereotype <<Data Access Object>>. Data Access Objects represent the integration tier that connects J2EE applications with a legacy system where Transfer Object data is stored. Guidelines for designing Data Access Objects are discussed later in this chapter.
Optimizations
Because the design model is intended to be implemented, optimizations such as factoring out common attributes into an abstract super class are encouraged. For example, the ID attribute common for all entities could be factored out and placed in a separate Transfer Object interface and corresponding abstract base class.
Another example is the case in which an entity has more than one subclass containing attributes and identifier. In this case, each subclass must be mapped to a Transfer Object interface and a corresponding Transfer Object class, where each class implements the base Transfer Object interface. In order to avoid replication, the base Transfer Object interface can be complemented by an Abstract<base Transfer Object Interface Name> class, which is extended by the Transfer Object implementations. Note, however, that the abstract Transfer Object must not have a separate Data Access Object implementation, since it is not possible to create instances of the abstract Transfer Object.
Transfer and Data Access Object Class Diagram Examples
Figure 2.4 shows a class diagram containing Transfer Object implementation classes. Note that the Transfer Object interfaces as well as methods and attributes have been omitted in this figure.:
Figure 2.4. Transfer Object implementation classes
Figure 2.5 shows a class diagram containing Data Access Objects. Note that methods have been omitted in this figure.
Figure 2.5. Data Access Objects