Monolithic applications built in this manor are difficult, if not impossible to unit test. They are difficult, if not impossible, to migrate from DB structure to DB structure. They make it difficult for you to truly own your Business Logic and not have the class structure dictated to you by a one-to-one relationship between class and table. They limit your freedom, your ability to maintain your work, and, in the long run, are much more expensive to upkeep.
What you want is an application architecture that permits unit testability. One that separates your concerns so that your Data Structure and your Business Logic class diagram only look similar when that similarity fits the needs of both functions. A design that permits you to minimize the unintended impact of code changes as much as humanly possible, and to keep the number of lines required to change any given aspect of it's functionality to the bare minimum. A design that allows you to have more than one UI, if needs dictate.
The most simple structure that provides for each of these needs is the three tier structure. It looks like this.
A Core project holds all your business logic. This is where you define the entities that you require to check off all the requirements on the spec sheet. These entities should be entirely code driven- unaware of the fact that they exist on SQL or in any other database structure. Unaware of the fact that they are being manipulated by a Windows program or a Webservice or any other front end. Do what I do, and don't permit the core project to reference System.Data or System.Windows. The reference direction will prohibit it from accessing functions in the Data and UI assemblies.
The Data project is where you want all your SQL interaction to reside. It will consist of the mappings of the persist-able business objects to the database behind the scenes, as well as any-and-all direct queries that the UI might need to run. The Data assembly should not know nor care what UI technology it is providing data for, and should not be intelligent about the purpose of the Core objects. As far as Data is concerned, it's only function is to create Core objects and return them to whatever wants them. I prefer NHibernate for a DRM solution in this assembly.
Finally, the UI layer is where you want any and all code relating to the presentation of data and interaction with the end user. This technology could be WPF, or WinForms, or webforms, or Silverlight, or even a webservice. It is whatever makes the most sense. But whatever it is, it should not contain any business logic or sql interaction code.
The hardest part of this structure is keeping yourself honest. It is tempting, hell, even easy, to write business logic in the UI layer by accident. A line of code that starts off as a simple call to a parameterless constructor one day may eventually morph into several lines that instantiate a business object and set up its default values, such as the creation date and name of creator. When requirements for prompts during certain procedures come along, it is very tempting to simply write a call to MessageBox in the Core assembly.
These temptations must be resisted.

0 comments:
Post a Comment