13.6. Guideline: Design with Layers

The essential ideas of using layers [BMRSS96] are simple:

Some more design issues are covered later, starting on p. 559. The idea is described as the

Layers pattern in [BMRSS96] and produces a

layered architecture . It has been applied and written about so often as a pattern that the

Pattern Almanac 2000 [Rising00] lists over 100 patterns that are variants of or related to the Layers pattern.

Using layers helps address several problems:

The purpose and number of layers varies across applications and application domains (information systems, operating systems, and so forth). Applied to information systems, typical layers are illustrated and explained in Figure 13.4.

Figure 13.4. Common layers in an information system logical architecture.[1]

[View full size image]

[1] The width of the package is used to communicate range of applicability in this diagram, but this is not a general UML practice. AKA means Also known As.

The

Application layer in 567.

Benefits of Using Layers

Guideline: Cohesive Responsibilities; Maintain a Separation of Concerns

The responsibilities of the objects in a layer should be strongly related to each other and should not be mixed with responsibilities of other layers. For example, objects in the UI layer should focus on UI work, such as creating windows and widgets, capturing mouse and keyboard events, and so forth. Objects in the application logic or "domain" layer should focus on application logic, such as calculating a sales total or taxes, or moving a piece on a game board.

UI objects should not do application logic. For example, a Java Swing

JFrame (window) object should not contain logic to calculate taxes or move a game piece. And on the other hand, application logic classes should not trap UI mouse or keyboard events. That would violate a clear

separation of concerns and maintaining

high cohesion basic architectural principles.high cohesion p. 314

Later chapters will explore these important principles, plus the

Model-View Separation Principle , in greater detail.

Model-View p. 209

Code: Mapping Code Organization to Layers and UML Packages

Most popular OO languages (Java, C#, C++, Python, …) provide support for packages (called namespaces in C# and C++).

Here's an example, using Java, for mapping UML packages to code. The layers and packages illustrated in Figure 13.2 can map to Java package names as follows. Notice that the layer name is used as a section of the Java package name:

// --- UI Layer

com.mycompany.nextgen.ui.swing

com.mycompany.nextgen.ui.web

// --- DOMAIN Layer

// packages specific to the NextGen project

com.mycompany.nextgen.domain.sales

com.mycompany.nextgen.domain.payments

// --- TECHNICAL SERVICES Layer

// our home-grown persistence (database) access layer

com.mycompany.service.persistence

// third party

org.apache.log4j

org.apache.soap.rpc

// --- FOUNDATION Layer

// foundation packages that our team creates

com.mycompany.util

Notice that, to support cross-project reuse, we avoided using a specific application qualifier ("nextgen") in the package names unless necessary. The UI packages are related to the NextGen POS application, so they are qualified with the application name

com.mycompany.nextgen.ui.* . But the utilities we write could be shared across many projects, hence the package name

com.mycompany.utils , not

com.mycompany.nextgen.utils .

UML Tools: Reverse-engineer Package Diagrams from Code

As mentioned earlier, a great use for a UML CASE tool is to reverse-engineer the source code and generate a package diagram automatically. This practice is enhanced if you use the recommended naming conventions in code. For example, if you include the partial name ".ui." in all packages for the UI layer, then the UML CASE tool will automatically group and nest sub-packages under a "ui" package, and you can see the layered architecture in both code and package diagram.

Definition: Domain Layer vs. Application Logic Layer; Domain Objects

This section describes a simple but key concept in

OO

design!

A typical software system has UI logic and application logic, such as GUI widget creation and tax calculations. Now, here's a key question:

How do we design the application logic with objects?

We could create one class called

XYZ and put all the methods, for all the required logic, in that one class. It could technically work (though be a nightmare to understand and maintain), but it isn't the recommended approach in the spirit of OO thinking.

So, what is the recommended approach? Answer: To create software objects with names and information similar to the real-world domain, and assign application logic responsibilities to them. For example, in the real world of POS, there are sales and payments. So, in software, we create a

Sale and

Payment class, and give them application logic responsibilities. This kind of software object is called a

domain object . It represents a thing in the problem domain space, and has related application or business logic, for example, a

Sale object being able to calculate its total.

Designing objects this way leads to the application logic layer being more accurately called the

domain layer of the architecturethe layer that contains domain objects to handle application logic work.

What's the Relationship Between the Domain Layer and Domain Model?

This is another key point: There's a relationship between the domain model and the domain layer. We look to the domain model (which is a visualization of noteworthy domain concepts) for inspiration for the names of classes in the domain layer. See Figure 13.5.

Figure 13.5. Domain layer and domain model relationship.

[View full size image]

The domain layer is part of the software and the domain model is part of the conceptual-perspective analysisthey aren't the same thing. But by creating a domain layer with inspiration from the domain model, we achieve a

lower representational gap , between the real-world domain, and our software design. For example, a

Sale in the UP Domain Model helps inspire us to consider creating a software

Sale class in the domain layer of the UP Design Model.

Definition: Tiers, Layers, and Partitions

The original notion of a

tier in architecture was a logical layer, not a physical node, but the word has become widely used to mean a physical processing node (or cluster of nodes), such as the "client tier" (the client computer). This book will avoid the term for clarity, but bear this in mind when reading architecture literature.

The

layers of an architecture are said to represent the vertical slices, while

partitions represent a horizontal division of relatively parallel subsystems of a layer. For example, the

Technical Services layer may be divided into partitions such as

Security and

Reporting (Figure 13.6).

Figure 13.6. Layers and partitions.

Guideline: Don't Show External Resources as the Bottom Layer

Most systems rely on external resources or services, such as a MySQL inventory database and a Novell LDAP naming and directory service. These are

physical implementation components, not a layer in the

logical architecture.

Showing external resources such as a particular database in a layer "below" the Foundation layer (for example) mixes up the logical view and the deployment views of the architecture.

Rather, in terms of the logical architecture and its layers, access to a particular set of persistent data (such as inventory data) can be viewed as a sub-domain of the

Domain Layerthe

Inventory sub-domain. And the general services that provide access to databases may be viewed as a Technical Service partitionthe Persistence service. See Figure 13.7.

Figure 13.7. Mixing views of the architecture.

[View full size image]