Wednesday, August 3, 2011

Designing the Components of an Application or Service


Component Types

An examination of most business solutions based on a layered component model
reveals several common component types. Figure 2.1 shows these component types
in one comprehensive illustration.
Note: The term component is used in the sense of a piece or part of the overall solution. This
includes compiled software components, such as Microsoft .NET assemblies, and other
software artifacts such as Web pages and Microsoft® BizTalk® Server Orchestration schedules.
Although the list of component types shown in Figure 2.1 is not exhaustive, it
represents the common kinds of software components found in most distributed
solutions. These component types are described in depth throughout the remainder
of this chapter.


Figure 2.1

The component types identified in the sample scenario design are:
1. User interface (UI) components. Most solutions need to provide a way for users
to interact with the application. In the retail application example, a Web site lets
customers view products and submit orders, and an application based on the
Microsoft Windows® operating system lets sales representatives enter order data
for customers who have telephoned the company. User interfaces are implemented
using Windows Forms, Microsoft ASP.NET pages, controls, or any other
technology you use to render and format data for users and to acquire and
validate data coming in from them.

2. User process components. In many cases, a user interaction with the system
follows a predictable process. For example, in the retail application you could
implement a procedure for viewing product data that has the user select a
category from a list of available product categories and then select an individual
product in the chosen category to view its details. Similarly, when the user
makes a purchase, the interaction follows a predictable process of gathering data
from the user, in which the user first supplies details of the products to be purchased,
then provides payment details, and then enters delivery details. To help
synchronize and orchestrate these user interactions, it can be useful to drive the
process using separate user process components. This way the process flow and
state management logic is not hard-coded in the user interface elements themselves,
and the same basic user interaction “engine” can be reused by multiple
user interfaces.

3. Business workflows. After the required data is collected by a user process, the
data can be used to perform a business process. For example, after the product,
payment, and delivery details are submitted to the retail application, the process
of taking payment and arranging delivery can begin. Many business processes
involve multiple steps that must be performed in the correct order and orchestrated.
For example, the retail system would need to calculate the total value of
the order, validate the credit card details, process the credit card payment, and
arrange delivery of the goods. This process could take an indeterminate amount
of time to complete, so the required tasks and the data required to perform them
would have to be managed. Business workflows define and coordinate longrunning,
multi-step business processes, and they can be implemented using
business process management tools such as BizTalk Server Orchestration.

4. Business components. Regardless of whether a business process consists of a
single step or an orchestrated workflow, your application will probably require
components that implement business rules and perform business tasks. For
example, in the retail application, you would need to implement the functionality
that calculates the total price of the goods ordered and adds the appropriate
delivery charge. Business components implement the business logic of the
application.

5. Service agents. When a business component needs to use functionality provided
in an external service, you may need to provide some code to manage the semantics
of communicating with that particular service. For example, the business
components of the retail application described earlier could use a service agent
to manage communication with the credit card authorization service, and use a
second service agent to handle conversations with the courier service. Service
agents isolate the idiosyncrasies of calling diverse services from your application,
and can provide additional services, such as basic mapping between the
format of the data exposed by the service and the format your application
requires.

6. Service interfaces. To expose business logic as a service, you must create service
interfaces that support the communication contracts (message-based communication,
formats, protocols, security, exceptions, and so on) its different consumers
require. For example, the credit card authorization service must expose a service
interface that describes the functionality offered by the service and the required
communication semantics for calling it. Service interfaces are sometimes referred
to as business facades.

7. Data access logic components. Most applications and services will need to
access a data store at some point during a business process. For example, the
retail application needs to retrieve product data from a database to display
product details to the user, and it needs to insert order details into the database
when a user places an order. It makes sense to abstract the logic necessary to
access data in a separate layer of data access logic components. Doing so centralizes
data access functionality and makes it easier to configure and maintain.

8. Business entity components: Most applications require data to be passed between
components. For example, in the retail application a list of products must
be passed from the data access logic components to the user interface components
so that the product list can be displayed to the users. The data is used to
represent real-world business entities, such as products or orders. The business
entities that are used internally in the application are usually data structures,
such as DataSets, DataReaders, or Extensible Markup Language (XML) streams,
but they can also be implemented using custom object-oriented classes that
represent the real-world entities your application has to work with, such as a
product or an order.

9. Components for security, operational management, and communication: Your
application will probably also use components to perform exception management,
to authorize users to perform certain tasks, and to communicate with other
services and applications. These components are discussed in detail in Chapter 3,
“Security, Operational Management, and Communications Policies.”

Tuesday, August 2, 2011

General Design Recommendations for Applications and Services


When designing an application or service, you should consider the following
recommendations:

- Identify the kinds of components you will need in your application. Some
applications do not require certain components. For example, smaller applications
that don’t need to integrate with other services may not need business
workflows or service agents. Similarly, applications that have only one user
interface with a small number of elements may not require user process
components.

-  Design all components of a particular type to be as consistent as possible, using
one design model or a small set of design models. This helps to preserve the
predictability and maintainability of the design and implementation for all
teams. In some cases, it may be hard to maintain a logical design due to technical
environments (for example, if you are developing both ASP.NET- and Windowsbased
user interfaces); however, you should strive for consistency within each
environment. In some cases, you can use a base class for all components that
follow a similar pattern, such as data access logic components.

- Understand how components communicate with each other before choosing
physical distribution boundaries. Keep coupling low and cohesion high by
choosing coarse-grained, rather than chatty, interfaces for remote communication.


- Keep the format used for data exchange consistent within the application or
service. If you must mix data representation formats, keep the number of formats
low. For example, you may return data in a DataReader from data access logic
components to do fast rendering of data in Microsoft ASP.NET, but use DataSets
for consumption in business processes. However, be aware that mixing XML
strings, DataSets, serialized objects, DataReaders, and other formats in the same
application will make the application more difficult to develop, extend, and
maintain.

- Keep code that enforces policies (such as security, operational management, and
communication restrictions) abstracted as much as possible from the application
business logic. Try to rely on attributes, platform application programming
interfaces (APIs), or utility components that provide “single line of code” access
to functionality related to the policies, such as publishing exceptions, authorizing
users, and so on.


- Determine at the outset what kind of layering you want to enforce. In a strict
layering system, components in layer A cannot call components in layer C; they
always call components in layer B. In a more relaxed layering system, components
in a layer can call components in other layers that are not immediately
below it. In all cases, try to avoid upstream calls and dependencies, in which
layer C invokes layer B. You may choose to implement a relaxed layering to
16 Application Architecture for .NET: Designing Applications and Services
prevent cascading effects throughout all layers whenever a layer close to the
bottom changes, or to prevent having components that do nothing but forward
calls to layers underneath.

Monday, August 1, 2011

Loose coupling


Coupling refers to the degree of direct knowledge that one class has of another. This is not meant to be interpreted as encapsulation vs. non-encapsulation. It is not a reference to one class's knowledge of another class's attributes or implementation, but rather knowledge of that other class itself.
Strong coupling occurs when a dependent class contains a pointer directly to a concrete class which provides the required behavior. The dependency cannot be substituted, or its "signature" changed, without requiring a change to the dependent class. Loose coupling occurs when the dependent class contains a pointer only to an interface, which can then be implemented by one or many concrete classes. The dependent class's dependency is to a "contract" specified by the interface; a defined list of methods and/or properties that implementing classes must provide. Any class that implements the interface can thus satisfy the dependency of a dependent class without having to change the class. This allows for extensibility in software design; a new class implementing an interface can be written to replace a current dependency in some or all situations, without requiring a change to the dependent class; the new and old classes can be interchanged freely. Strong coupling does not allow this.
This is a UML diagram (created in IBM Rhapsody) illustrating an example of loose coupling between a dependent class and a set of concrete classes, which provide the required behavior:
Loose Coupling Example.JPG
For comparison, this diagram illustrates the alternative design with strong coupling between the dependent class and a provider:
Strong Coupling Example.JPG

[edit]Measuring data element coupling

The degree of the loose coupling can be measured by noting the number of changes in data elements that could occur in the sending or receiving systems and determining if the computers would still continue communicating correctly. These changes include items such as:
  1. adding new data elements to messages
  2. changing the order of data elements
  3. changing the names of data elements
  4. changing the structures of data elements
  5. omitting data elements

[edit]Methods for decreasing coupling

Loose coupling of interfaces can be dramatically enhanced when publishers of data transmit messages using a flexible file format such as XML to enable subscribers to publish clear definitions of how they subsequently use this data. For example, a subscriber could publish the collection of statements used to extract information from a publisher's messages by sharing the relevant XPath expressions used for data transformation. This would allow a responsible data publisher to test whether their subscriber's extraction methods would fail when a published format changes.
Loose coupling of services can be enhanced by reducing the information passed into a service to the key data. For example, a service that sends a letter is most reusable when just the customer identifier is passed and the customer address is obtained within the service. This decouples services because services do not need to be called in a specific order (e.g. GetCustomerAddress, SendLetter)
Note that loose coupling is not universally positive. If systems are de-coupled in time using Message-oriented middleware, it is difficult to also provide transactional integrity. Data replication across different systems provides loose coupling (in availability), but creates issues in maintaining synchronisation.