FREE hit counter and Internet traffic statistics from freestats.com

Thursday, November 11, 2004

Guidelines for Software Architecture

Recently, I've been thinking more about what a software architect does and trying to formulate some basic axioms or guidelines to keep in the front of my mind. To that end I thought Steve Cohen's thoughts on what "Enterprise Ready" means are useful.

Anyway, here are a few guidelines (not original of course) that I came up with for a course I teach on patterns and architecture in .NET that apply to a typical layered architecture (presentation, business, data).

  • Design components of a particular type to be consistent. By this we mean that components within a particular layer should use common semantics and communicate in a consistent fashion. One example is that in the Data Services layer all the Data Access Logic components should use the same mechanism (DataSets, data readers, custom objects) to marshal data.
  • Always run in process if possible. The basic facts of physics dictates that code running in-process is orders of magnitude faster than code running out of process. The reasons to run out of process include a need for process isolation, platform interoperability, and occasionally CPU overload (although “scaling out” often addresses this issue).
  • Only have dependencies down the call stack. In layered architecture it is important to not tightly couple the components lower in the stack to those higher. This allows the application to be modified more easily. Note that a strict rule such as never having the presentation call the data services directly is not implied by this guideline.
  • Separate model from view. Where possible try and abstract the data (the model) from the how the data is presented (the view). This can be done through the use of web user controls and the Bridge Pattern.
  • Use service accounts when possible. The use of service accounts to run server processes such as ASP.NET and Component Services allows for simplified security by not requiring delegation. It also allows connection pooling to occur.
  • Force common functionality up the inheritance hierarchy. One of the common patterns used is the Layer Supertype. This pattern promotes code reuse by implementing common code for an entire layer in an abstract base class whenever possible.
  • Keep policy code abstracted from application code. When possible, try to keep security, caching, logging and other “policy” code independent of the application or domain logic. This allows it to more easily be changed without affecting the functionality of the application.


No comments: