So we know technology changes.
What do we do about it? How do we prepare for it architecturally?
Layering software is a technique to abstract away from a particular 'thing' so that you can gain some lessened coupling (or negate it completely).
Take for example data access. You don't want your Application's business entities (business or domain objects) coupled directly to the schema in your database or to the technology of your database.
For example, in data access you might have code like this:
using(SqlConnection connection = new SqlConnection(settings.ConnectString))
{
connection.Open();
.....
}
You don't want this type of code directly in your customer class definition because what if you start using an Odbc database? What if you start using an XML file? What if you start using a web service?
Layering software for me in the past simply means having a class/interface library that is shared/common between two layers of class libraries.
For example:
I would have BusinessEntities.dll and SqlDataAccess.dll. Well for BusinessEntities to talk to SqlDataAccess.dll i will want some 'common abstractions' between the two.
I will call that DataAccessInterfaces.dll and I will put things in it like this:
abstract class CustomerDataProvider{}
or maybe
interface ICustomerDataProvider
{
ICustomerData GetCustomer(string custId);
}
and
interface ICustomerData
{
string FirstName{get;set;}
string LastName{get;set;}
}
You're probably thinking, wow this adds a lot of architectural complexity to my project. You're right...
So when do you do something like this?
Well I believe in YAGNI and Simplest thing that could work... so the very first time that you need to make a change like this is the time to architectural change it. If you're working in a fairly fast paced rapidly changing environment where constant refactoring and testing is possible this can work for you.
Now, let's talk tiers though.
From what I've seen, tiers are really no different than layers in how you implement them (especially with things like Windows Communication Foundation and web services because you can use the same layer definitions and just add a little webservice code into them and turn your ICustomerProvider into a web service class)
So anyhow, why do we use tiers?
Tiers provide us scalability for one.
If my data tier is on a seperate machine, then I can offload all that disk IO to a machine that's build especially for that (i'm thinking NAS, SAN, or other high IO capable device).
If my application tier (web services) are on a seperate web server (or server farm) then i get the benefit of connection pooling to the database (instead of 1 connection per fat client)
If my web server tier is on a seperate web server, then i get added security of protecting my webservice, connection strings, and enterprise data from being in the DMZ.
Then finally my client application is on my customer's machine (web browser or thin client). This allows for a very thin install, rapid change of the user interface without being muddled with business rules (business rules would be on the application tier).
It allows me to change business rules without impacting any presentation (so long as i've got a way to handle cross cutting concerns like validation :) but you should read elsewhere for that).
Anyhow, food for thought...
Please comment on how you've seen multi layered and tiered architectures used.