One of the best reasons, these days, for using Distributed COM is to assist companies who are moving their information systems from a two-tier architecture to an N-tier architecture. This transition requires the design and creation of a middle tier of business objects. These business objects are placed between client applications and database servers. Distributed COM can serve as the foundation for these types of systems. Before examining the requirements of an N-tier architecture, let's look at two-tier systems and their strengths and limitations.
Figure 1-3 shows the layout of a typical two-tier information system. It's currently the most common architecture for applications built on multiuser database systems. Client applications connect directly to a database management system (DBMS), such as ORACLE or Microsoft SQL Server. Each client computer requires a vendor-specific library, such as an ODBC driver for ORACLE or SQL Server. Client applications are typically required to log on to the DBMS independently and maintain an exclusive connection. The client application is then responsible for preparing and sending SQL statements directly to a server. The client is also responsible for dealing with messages, errors, and streams of data returned by the database engine.
Figure 1-3. Typical two-tier applications require each user to acquire a direct connection to a database server.
In a two-tier system, the client application commonly maintains some or all of the application's business logic. Whenever the business logic changes, the client application must be rebuilt and redistributed to all the client desktops. This can be a fairly painful undertaking, and as a result, a fairly pressing need usually has to be present to justify the distribution of a new version. As soon as a company puts two or more client applications into production, the odds are very high that redundant code for the same business logic will spread across several applications. This creates problems with both the maintenance and the consistency of a company's business logic. These two problems are common weaknesses of a two-tier system.
Two-tier systems have benefited from the introduction of stored procedures. Stored procedures are routines written in a vendor-specific dialect of SQL that allow business logic and data access logic to be stored and run on the database server. All popular client/server DBMSs offer one form of stored procedures or another. Figure 1-4 demonstrates how this logic can be shared across several client applications. Business logic can be maintained centrally by a database server. Client applications call these stored procedures by name. This makes it easy to maintain business logic simply by rebuilding stored procedures. Client applications don't care whether they are rebuilt as long as the names of the stored procedures remain the same.
Figure 1-4. Stored procedures give programmers a way to centralize business logic in a two-tier application.
Stored procedures also offer improvements in performance and scalability. The SQL code in a stored procedure is parsed and normalized when it's created by a developer. Stored procedures are also optimized and saved in native machine language. When a stored procedure is called, it's all ready to go. For these reasons, it's much faster to call a stored procedure than to submit a raw SQL statement that must undergo all these steps at every single execution. The performance gains that you can attribute to the use of stored procedures are significant. Database systems can usually accommodate a client base twice the size simply by using stored procedures instead of raw SQL.
A two-tier architecture is at its best in an information system that employs a single data source. Unfortunately, the performance gains and centralization of business logic within stored procedures are usually unattainable when the system's data is spread across multiple servers. SQL Server does have remote stored procedures, but this feature works only when every database server uses SQL Server as its DBMS. In systems with heterogeneous data sources, a two-tier architecture begins to quickly break down, as you can see in Figure 1-5.
Two-tier systems have been widely deployed in the industry, and consequently, the problems associated with them are very well known. Most problems arise under two circumstances: The data is being accessed by multiple client applications, and the system's data is stored across multiple database servers.
Figure 1-5. Two-tier applications are very costly to create, maintain, and extend when data is stored in multiple, heterogeneous data sources.
Here's a summary of the most frequently recurring problems that make a two-tier architecture hard to work with:
These problems of a two-tier architecture can be solved like many other problems in computer science. The answer is to add a layer of indirection. The introduction of a set of business objects can serve to decouple client applications from data access code, as shown in Figure 1-6.
Figure 1-6. Introducing a middle tier of business objects eliminates costly dependencies between client applications and database servers.
Business objects are like stored procedures in that they allow you to centralize your logic and reuse it across several client applications. Unlike stored procedures, business objects make it easy to access data across several data sources, even when these data sources are of heterogeneous formats. Furthermore, these business objects can be written in languages such as Visual Basic, C++, and Java, which offer many advantages over writing and maintaining the same logic in a vendor-specific dialect of SQL.
In Windows NT-based networks, these business objects can be deployed using COM as the foundation. COM can serve as the basis for communications between the client applications and the middle-tier objects. This means that computers running the client applications need only to be COM-aware. They don't require desktop database drivers as they do in the two-tier model.
Another advantage is that COM allows a middle-tier programmer to update these business objects without requiring a recompilation and redistribution of client applications. This makes it very easy to change an application's business logic or data access code because the client applications are completely shielded from the system's infrastructure. A system's data can change storage formats, and new database servers can be brought on line painlessly. The necessary modifications are made in the middle tier, allowing client applications to remain in production unaltered.
One of the first questions that usually comes to mind is, "Where should each of these layers be deployed?" Figure 1-7 illustrates two possible scenarios for deployment. Three tiers don't always mean three computers. In a small deployment, the business code and the database server might run on the same computer. In a larger system, the data can be kept in one or more dedicated database servers while the business objects run on a separate host. Some deployment schemes offer greater scalability, reliability, and fault tolerance than others. When people speak of three-tier systems, they're speaking of three distinct logical levels. The physical deployment can vary and can be easily changed after a system is put into production. The location transparency afforded by COM makes it possible to make these deployment changes with few or no changes to application code.
Figure 1-7. The mapping between business objects and the data access layer can start simple and become more complex later without affecting client applications.
Some people use the term three-tier, while others prefer the term N-tier. The term N-tier simply means a system has at least three tiers. Figure 1-8 shows a more complex set of physical layers. In the N-tier model, the business and data access tiers can be arbitrarily complex. The best part about this model is that the client application knows only about the business tier. All the additional complexity going on behind a visible set of business objects doesn't concern a client application. The primary design goal in a N-tier system, therefore, is to hide as much of this complexity as possible from the client applications that make up the presentation layer.
Figure 1-8. One of the greatest strengths of an N-tier architecture is that it hides the complexity and evolution of an enterprise's Information Systems (IS) infrastructure.
Before jumping off the deep end and abandoning your existing two-tier system, you should understand the costs of designing and deploying a three-tier system. Up front, such costs include those of designing and writing code for a set of objects that model your business processes, which frequently isn't a trivial undertaking. Second, a distributed application requires lots of infrastructure support. In your old two-tier system, you had a powerful DBMS such as ORACLE or SQL Server to manage connections, pool threads, monitor transactions, and perform a host of other services that are incredibly important to system throughput and scalability. Who will be responsible for all that work in an N-tier system?
A middle-tier application running a set of business objects must provide a similar set of services. Scalable N-tier systems require sophisticated frameworks to supply these services. The cost of putting together a distributed framework might not be warranted if a two-tier system is adequate. In particular, a smaller system with a single database server and one or two client applications might be better off staying with a two-tier model.
The obvious benefit of a three-tier system is that once it is put in place, it's far easier to maintain and extend. For large and complex systems that deploy many client applications or data sources, the initial investment is recouped quickly. Future client applications can be written against a preexisting set of business objects. Database servers can be changed or brought on line with minimal impact. And most important, business logic can be modified quickly and at a much lower cost.