I recently put in a proposal for a job and I missed out on it. The competition offered to do it for nothing, and I couldn’t match that price. There were reasons for this which I needn’t go into now and we all parted amicably with no hard feelings.
However, it got me thinking about N-Tier programming. The proposal I submitted was for a small addition to an existing application which is currently written in MSAccess. The application is networked and the company is growing. In my mind, not a good candidate for an Access application. In fact, I can think of no good candidate for an Access application, but that is probably due to prejudice rather than unbiased reasoning.
At the same time I am writing an application for a builder which will sit on one PC. In many respects the two applications are very similar, it is only the size which differs. And the size is different in two respects.
First, the builder’s application is not as complex not does it require the same amount of functionality as the other program. Although it is not significantly different in this respect. The other difference is that the builder’s app will run on one PC and the database will be much smaller – perhaps a similar number of tables, but certainly much less data. Because of the similarities I decided to build the builder’s app in a way which would scale to suit the size of the other app. Not that it needs to, but I can then use it to show the other people the kind of thing they can get in the future. Plus it is more interesting to build it this way.
So I decided to go with a 3-tier model. A User Interface layer, a Business layer, and a data layer. Pretty standard.
Here is the problem. If there were three physical layers then the data layer would sit on the database server, the business layer would sit on a business server, and the UI layer would sit on the users’ PCs.
But that is pretty unusual for the types of businesses that I deal with. Most are small to medium sized and they don’t have two servers. The usual set up is that one of the User’s PCs acts as the server with Ethernet or something similar connecting the other PCs. The alternative is one dedicated server. And in a lot of cases there is only one PC and no network at all.
I could, of course, build the system with the three logical layers in place. That would mean that objects are serialized and passed through the network between each layer. There is nothing wrong with that approach. It can get a bit complex, but once you have figured out what classes you need on each layer then it is more or less plain sailing.
There are two problems with that approach. First I have to use MSAccess databases. I hope that soon we can move to SQL 2005, but at the moment for both applications, I am stuck with Access. And for the 3-tier approach to work efficiently I think I really need to use stored procedures.
The second problem is that it is overkill. I am never going to have a network of hundreds of PCs. Scalability is a great buzz word, but often it is just irrelevant. In this case there is no justification for creating and serializing this many objects. Especially for those cases where it is running on just one PC.
So now I have decided that a 2-tier approach is better, at least performance wise. But where does the business layer go? These are the possibilies.
First, in the case of just one PC it doesn’t really matter. Everything could go in one layer, but breaking it up probably helps future maintenance. And if, in the future, they change to a different type of database, then sticking the business layer into the data layer seems sensible.
Secondly, if there is one dedicated server then having the business layer on that server also makes sense. The data server holds all the data, performs all the database functions, carries out all the validations and applies any other business rules, creates the objects, serializes them into a data stream and sends them up the network to the user. Everyone is happy.
But the most common set up amongst my clients is the one where one of the User’s PCs acts as the server. And the model I just described means that this PC does nearly all the work. And unfortunately, there are many applications which are set up this way. This poor user can get very little work done because the PC is grinding to a halt under the work load.
In this case, it makes more sense to put the business layer with the UI and let every user share the work load. But it doesn’t scale well. And when the company upgrades to a dedicated server they won’t get the performance boost they expected because of the work being carried out by, often old and under-speced, PCs.
I wish there was a simple answer. But I am afraid there isn’t.
So which way am I building this app? I am putting the business layer with the data layer, but I may yet change my mind.