Designing in Tiers

Terms such as three-tier, n-tier, and multitier have been hotly hyped in programming circles. These terms mean widely different things to different people. Some use them to refer to the process of physically partitioning an application, and others use them to talk about logically separating the functionality of an application into layers. This book uses the latter approach.

Three-tier architecture began as an extension of the commonsense idea that different code performs different types of tasks. Three-tier architecture separates an application's functionality into three categories: presentation logic, business logic, and data logic (as shown in Figure 10-4). The presentation logic handles the user interface tasks. The business logic handles the company-specific processes. The data logic just inserts, deletes, modifies, and retrieves records from a back-end data store such as a database. The critical concept in three-tier design is that code in a given layer can communicate only with an adjacent layer. In other words, the presentation logic can't communicate directly with the database. Instead, it has to forward its request through a layer of business objects.

Three-tier design was a fundamental improvement over most client-server designs and was critically important in the world of Visual Basic, where developers were often seduced into placing database logic directly in form event handlers. By adopting a strict three-tier design, it became easier to separate application logic and thereby easier to reuse, replace, and test individual units of functionality.

There's no way to escape three-tier design as a basic organizing principle. A Web page or Windows Forms page should never create an ADO.NET object directly. By creating a separate class to handle this task, you ensure that the code can be easily updated to use a different database structure or data access technology. Your changes are confined to one component instead of being spread haphazardly throughout the user interface logic of a client application.

Figure 10-4. Three-tier design

graphics/f10dp04.jpg

Business Objects

If you're a diehard programming veteran, you've probably noticed that I haven't yet used the term business objects in this chapter. There is a definite reason for this omission. Quite simply, many business object designs just don't work.

One of the most common problems in three-tier design is the requirement that business rules be placed exclusively in the middle tier. To achieve this goal, many developers created three-tier designs based on stateful objects (such as the Account class used earlier in Listing 10-1) that could validate settings through property procedures. These applications were perfect examples of object-oriented three-tier design and they performed horribly.

For that reason, I concentrate on a different type of modeling in this book. I call this design information packages and service providers, but it's also sometimes known as entity/service modeling. Later, when we explore distributed design patterns, you'll discover that the old rules of three-tier design are just as important with service providers and information packages, provided you understand the tradeoffs.

Rules

When designing a new system, the first task you undertake is to determine how you can divide the functionality into components. The second task is to decide where business rules (typically company-specific rules for data validation and data processing) will take place.

In three-tier design, the goal is to place as many rules as possible in the business layer of the application. This has many benefits. It enables you to modify the rules, which tend to change frequently, without disturbing the rest of the application or redeploying new software. It also enables you to support more than one type of client (for example, an ASP.NET Web page and a Windows desktop application) without creating two copies of the same code. And, as you saw earlier with the AccountUtility.TransferFunds method in Listing 10-3, moving the business logic away from the client also makes it easier to optimize this code (for example, with transactions and stored procedures) and can even help to keep it secure.

However, the ideal of locating business rules in middle-tier components is not always practical, for both performance and usability reasons.

User Interface Rules

For example, some business rules absolutely belong in the user interface such as those that restrict invalid options in a window. An application that needs to query a remote object before it can report a user input error just isn't intuitive enough for the average user, who needs to be guided at every step of the way and more importantly prevented from entering invalid input in the first place. Leaving these rules out of the presentation tier can also hamper performance.

Consider, for example, the extreme example of what might happen if you create a window that doesn't prevent users from typing letters into an Account ID text box. The user of this application might mistakenly type a name. The application will then contact the remote object, attempt the operation, and generate an error, which it will report back to the client. By the time the information is correctly entered and submitted, the poor design might have already resulted in several additional network calls, reducing the overall performance of the system.

Note

One good rule of thumb is that if you have enough information in the client (presentation layer) to do data validation, do it there. Remember that you should try not to hard-code any information. For example, enforcing field-length restrictions in a text box can cause quite a headache if the allowed length of the underlying database field changes. The best approach is to determine the length of the field programmatically, if possible, perhaps by reading the DataColumn information in the DataSet and then configuring the corresponding user interface controls dynamically. Of course, this requires additional coding.


Data Layer Rules

Other rules are always dealt with in the data layer. These include the rules that verify referential integrity (for example, ensuring that you can't create a child record that refers to a nonexistent parent) and identity integrity (for example, ensuring that you can't create two identical copies of a unique field). In some cases, the business layer might perform a similar check before attempting the operation, which might allow it to save a database trip in the case of an error. However, most of these rules depend on the information that is already in the database, and the business object is in no position to query additional rows just to verify that this restriction is followed.

The Database Can Execute Business Logic

Performance tests indicate that in many cases you can improve application performance by moving business logic to the stored procedure layer. Instead of creating a component that iterates through a collection of order items and inserts each one separately, for example, you can create a more powerful stored procedure that inserts all the orders simultaneously and performs any required validation or preprocessing. Typically, the database can precompile the stored procedure code and thereby execute it more quickly.

Think carefully, however, before you move your logic to the database layer. Advanced stored procedures can be quite difficult to create because you must use script-based languages such as Transact-SQL and deal with custom error codes and database-specific commands. Generally, most systems are better off including the business rules in .NET objects, where they are easier to alter and troubleshoot. In addition, placing time-consuming logic in the database can increase performance at the cost of scalability because the database can't be load-balanced in the same way that a stateless component can. If sheer performance is absolutely critical, however, you might want to try some performance testing to determine whether data layer business logic can save you some time.



Microsoft. NET Distributed Applications(c) Integrating XML Web Services and. NET Remoting
MicrosoftВ® .NET Distributed Applications: Integrating XML Web Services and .NET Remoting (Pro-Developer)
ISBN: 0735619336
EAN: 2147483647
Year: 2005
Pages: 174

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net