Single-Tier and Two-Tier Architecture
Single-Tier and Two-Tier Architecture
A single-tier architecture is an architecture in which the entire application resides on the user's machine. Before
networking became so easy and cheap, this was frequently the design of choice. Nowadays you will find this
architecture used rarely and almost never in conjunction with enterprise data. The obvious drawback to single-
tier architecture is that the data lives on a local machine, and no one else can access it. In a fast-moving
enterprise where information is everything, this is not a good situation.
The advantage to this architecture, from a developer's standpoint, is that it is relatively simple to code. The
developer does not have to worry about security, concurrent access, network connectivity, or any of a hundred
other issues that plague multitier applications.
For the purposes of the modern enterprise, single-tier architecture no longer exists. Most of my experience with
this architecture has been relegated to upgrading small applications developed using Microsoft Access.
Frequently users will create spur-of-the-moment applications using a wizard to accomplish repetitive needs that
are only applicable to them. This type of application is often a candidate for being upgraded to a two-tier
application.
Figure 1-1: A two-tier application architecture
By its very nature, a two-tier application is not scalable beyond a certain point. There are several reasons for this.
One reason is the number of connections a database can maintain concurrently. Imagine that one million users try
to access the database at the same time…need I say more? There is no way to effectively manage the connections
to the database when the connections are being created on the user's machine (as opposed to being able to pool
database connections). Another reason why a two-tier application is not scalable beyond a certain point is
application functionality in relationship to the business process that the application supports. Take a situation
where a business process changes and the program has to be altered. The company may have to roll the
upgraded application out to 30,000 users, which is usually too cost prohibitive to do. Scalability does not have to
just reflect whether an application can support a growing number of users but also how expensive it is to support
them.
Then there is the concurrency issue; that is, what happens when two or more users try to access the same record
in the same database at the same time to make changes to it? Usually one or more users are blocked from making
changes, which can cause the application to temporarily hang. In a two-tier application, this can be both a
positive and a negative aspect of the application. The positive aspect is that one user cannot alter a record that
another user is modifying. The negative aspect is that it can cause the second user's query to wait if there is a
lock on the record they want to read. If the application is programmed correctly, the lock should not last for more
than a few milliseconds, but on some database platforms, if the user who placed the lock is prematurely
disconnected from the database, the result is a lock that cannot be removed except by the database administrator
or by the database after a certain period of time. This has the potential to cause numerous problems. This
particular issue is never a problem with a three-tier application, but other, more complicated issues appear with
regard to this aspect of the database (see the sidebar "Database Concurrency Issues").
So, with all of these issues, when is a two-tier architecture a good solution? Usually it is when there are only
going to be a small number of users who will ever use the application. When I say small number, I mean about
100 or fewer users. Another time to use two-tier architecture is when other applications will not need to access
the functionality provided by the two-tier application. Take for instance an application that performs some
function that is only needed in this one instance—you probably will not need to worry about incorporating this
functionality into other applications. Because the functionality does not need to be reused, there is no point in
creating a reusable component.
So, what is the major drawback to a two-tier system? Every time I have written a two-tier application for a small
number of users, someone has come up to me and said, "That is a great program, can we use it also?" And from
there it snowballs. All of a sudden, this little application I wrote for five users is suddenly being used by 15
people, and then 40 people, and then so on and so forth. Eventually someone comes to me with some serious
performance problems of the application. My typical answer comes across as something like, "No, you're kidding?"
At a certain point, sarcasm became a way of life for me….
However, there are things you, as a developer, can do to mitigate this risk. There is a right way and a wrong way
to write a two-tier application, and typically—you guessed it—the developer chooses the wrong way. The wrong
way takes less forethought when designing the application, which means the developer can show results almost
immediately. In the long term, though, development will slow because it is done on a "think up things as you go"
approach. The wrong way also causes an immense amount of work to be re-done when upgrading the application
from two to three tiers. And this happens more often than developers would like to believe. Figure 1-1 showed a
two-tier application that is not scalable beyond a certain point. However, Figure 1-2 shows a better way to build a
two-tier application.
Figure 1-2: Correct architecture for a two-tier application
The right way to build a two-tier application is to treat it as a three-tier application and just install all the
components on the user's local machine. This approach will cause development to initially be slower because
more thought needs to go into the application in the initial stages. But, after you develop this initial strategy, the
coding will go much faster and smoother, and many of the surprises that would normally catch you along the way
are handled before they become issues. By building the application this way, when performance problems start
cropping up, it is a small step to move the business logic and data access code off of the local machine and onto
an application server. Problem solved. The only issue you will really have to deal with is where to put the business
rules. (We talk a little more about object modeling and business rules in Chapter 3, "Creating the Application
Infrastructure.")