Distributed computer systems play an important role in this active business environment. Every aspect of the modern corporation—marketing, manufacturing, finance, customer support, and almost everything else you can think of—relies on its information technology (IT) assets. IT systems provide support for each organizational function. These systems must work together to provide seamless information access throughout the corporation. In the late 1990s, the scope of these applications is extending outside the enterprise as well. In particular, many companies are providing services to their customers over the Internet. In this environment, great software systems are strategic assets that differentiate companies that can compete effectively from those that will fall by the wayside.
For a company to remain competitive, IT systems must be responsive to changes in business and user requirements. Developers must be able to write applications quickly—and be able to modify them just as quickly. Flexible, incremental development methods that produce libraries of reusable code are key to a company's success.
In addition to time constraints, developers face enormously challenging application requirements. New applications are extremely demanding for a multitude of reasons, some of which are listed here:
Put all these together and we think you'll agree that distributed application development is just plain hard.
One of the main goals of every system software vendor is to find some way to make writing this type of application easier. And to a surprising extent, vendors agree on the overall approach: build applications from cooperating components, using a three-tier application architecture.
An application architecture is a conceptual view of the structure of an application. All applications contain presentation code, data processing code, and data storage code. Application architectures differ in how this code is packaged.
Many current applications are two-tier, or client/server, applications. In a two-tier architecture, a client process handles the data processing and presentation parts of the application. Data is stored on centrally administered server machines. Clients connect directly to the servers they need, often for the lifetime of the application.
Client/server applications work well in controlled environments in which the number of users can be estimated and managed and resources can be allocated accordingly. However, when the number of users is unknown or very large, the client/server architecture breaks down. Because each client connects to data servers directly, scalability is limited by the number of available data connections. Opportunities for reuse are limited because the clients are bound to the database formats. Each client application contains data processing logic, making the applications relatively large. (This type of client is sometimes called a fat client.) If the data processing logic ever needs to change, new applications must be distributed to every client machine.
A slight improvement comes from moving parts of the data processing, or business logic, to the data servers—for example, by using Microsoft SQL Server stored procedures. This architecture is sometimes called "two-and-a-half tier." Applications built on this model are somewhat more scalable, but not scalable enough to meet the needs of highly distributed applications. In addition, opportunities for reuse are limited.
Scalability and reuse can be improved significantly by introducing a third tier to the application architecture. In the three-tier model, presentation, business, and data access layers are logically separated, as illustrated in Figure 1-1.
Figure 1-1. The three-tier application model.
The presentation layer presents data to the user and optionally lets the user edit data. The two main types of user interfaces for PC-based applications are native and Web-based. Native user interfaces use the services of the underlying operating system. For example, on the Microsoft Windows platform, native user interfaces use the Microsoft Win32 Application Programming Interface (API) and Windows controls. Web-based user interfaces are based on Hypertext Markup Language (HTML), which can be rendered by a browser on any platform.
The business layer is used to enforce business and data rules. The presentation layer uses the services of the business layer. However, the business layer is not tied to any specific client; its services are available to all applications. Business rules can be business algorithms, business policies, legal policies, and so on—for example: "Users get a 10 percent discount for ads placed before Tuesday night" or "8.2 percent sales tax must be collected for all orders delivered to Washington State." Data rules help ensure that stored data is consistent across multiple stores—for example: "An order header must have at least one detail record" or "Money must not be lost or generated during transfers between bank accounts." Business rules are typically implemented in isolated code modules. Each rule is implemented in one place so that it can be easily updated in response to changing business needs. The code modules are usually stored in a centralized location so that multiple applications can use them.
The business layer has no knowledge of how or where the data it works on is stored. Instead, it relies on the data access services, which perform the actual work of retrieving and storing data in a database management system (DBMS) or any other data store. The data access services are also implemented in isolated code modules, encapsulating knowledge of the underlying data store. If the data store moves or changes format, only the data access services need to be updated. Each data access module is responsible for the integrity of a set of data—for example, for a table in a relational database.
It's important to recognize that this is a logical model, not a physical model. The term "three tier" does not imply three separate machines. The logical model encompasses a wide range of physical models, depending on where the services are deployed. Applications are constructed as logical networks of consumers and suppliers of services. Services are merely units of application logic that provide well-defined functionality.
This model promotes scalable applications. To create highly scalable applications, resources such as database connections must be shared. Instead of each client application consuming resources to access data servers directly, client applications communicate with business services. One instance of a business service can support many clients, reducing resource consumption and improving scalability, as shown in Figure 1-2. Since business services do not manage data directly, it's easy to replicate these services to support even more clients.
Figure 1-2. Resource use in two-tier and three-tier models.
Services can often be designed and implemented independent of any particular client application, providing flexibility and the potential for reuse in many applications. By encapsulating application logic behind well-defined public interfaces, developers create a body of reusable services that can easily be combined in new ways to create new applications. In addition, common functionality can easily be updated in response to changing business requirements, without impacting the client applications that rely on the functionality. This reduces the management and deployment costs of changing requirements.
The three-tier model can also help developers deal with existing, or legacy, systems. Developers can "wrap" access to existing systems within business logic or data access services. Client applications need to worry only about how to access the business logic, not how to access all the different legacy systems they might rely on. And if the legacy system is modified or replaced, only the wrapper needs to be updated.
The growing consensus in the industry is that future service-based applications will be implemented using components. Traditionally, services have been exposed through APIs. The programming models used by different APIs can vary dramatically, making it difficult for developers to learn and use them effectively. APIs are difficult to version as well. Object-oriented frameworks are another popular way to expose services, but they suffer from many of the same problems as APIs. In addition, frameworks are typically specific to one programming language.
Components provide a standard model for packaging services and exposing them to consumers. Components are "black boxes"—all their data and implementation details are completely hidden. Component services are exposed via public interfaces, and a common programming model is available for discovering and using these interfaces, regardless of the components being used. Unlike language-based object-oriented models, component models provide facilities to enable communication with components regardless of the development language the components are written in or the location of the deployed components.
A three-tier, component-based architecture alone does not produce a successful distributed application. High-performance, scalable, reliable server applications require a sophisticated infrastructure, as shown in Figure 1-3. Traditionally, application developers have needed to develop most of the code required to manage server processes, threads, database connections, and other resources, as well as security, administration, and other infrastructure code. The actual business logic is typically a small portion of the total application. Infrastructure code is extremely complex and difficult to implement in a scalable fashion.
Figure 1-3. Distributed application infrastructure.
Middleware is a category of system software that provides infrastructure code to help build distributed applications. Standard middleware is the glue that enables independently developed components to work together to create distributed applications. Middleware masks the underlying system complexity from application developers and is a key enabler for the three-tier component-based application architecture.
Developers will also need to be able to access existing data and applications, regardless of the type of host system. Thus, a second enabler of the application architecture is interoperability services between the selected middleware and existing systems, such as standard interprocess communications protocols or application gateways.
Finally, developers will need access to development tools that facilitate use of the application architecture and middleware services. For example, tools might be able to generate framework code for components automatically, reducing the amount of hand-coding that the developer needs to do. Debugging and troubleshooting tools are needed to help isolate problems occurring somewhere in the distributed application.
While system software vendors are in general agreement about the application architecture, there is a great deal of disagreement about the middleware, interoperability services, and tools you should use to implement your applications. After all, it's only natural that each vendor will recommend its own middleware, interoperability services, and tools.