Layers – Separating Software Concerns

Layering is one of the basic ways of seperating a software system into functionally logical areas – a concept known as Separation of Concerns. Separating code into layers results in a system that is more organised and therefore easier to develop, test, and maintain. A system that seperates concerns can also be described as “modular”.

In a simple 3-tier design you have 3 layers. These are typically Presentation, Business Logic, and Data Storage. The business Logic layer may itself be split into further layers such as

  • Service Layer
  • Domain Layer
  • Repository Layer
  • Data Mapping Layer

If the business logic layer resides on its own physical server, then a higher layer, such as the Presentation layer will need to communicate with it across the nertwork. To allow this communication, the Business Logic layer can have a Service layer at the top of its stack to allow requests from the upper layer using http or tcp for example. By keeping the communication loosely coupled, we could easily add and extra web server to cope with increased traffic that would call the same server hosting the service layer.

What is the Essence of Layered Architecture?

The layers of an application form a stack. The layer at the top of the stack “knows about” the layer immediatley beneath it only. Conversely, the lower layer is “agnostic” about the layer above it. By agnostic, I mean it receives method calls but is unaware of the type of object that is calling it. Why is this an advantage? Because we can re-use the lower layer and call its methods from somewhere else, thus making the application more easily extensible. An example would be a domain layer which makes calls down to the data mapping layer. The data mapping layer need not care about who is calling it, so we could make the same method calls from a repository layer for example.

Layer Supertypes

By partioning a particular area of functionality (a “concern”) into a layer we should see some commonality in the class members of objects in the layer. This allows you to use a common base type for that layer – A Layer Supertype.

For example, if all your domain objects require auditing information (when and by whom each object was created and changed), then you could create layer supertype which contains these members and is sub-typed by all domain objects…


 namespace Domain
{
    public class DomainBaseType
    {
        protected DateTime CreationDate { get; set; }
        protected string CreatedBy { get; set; }
        protected DateTime ChangedDate { get; set; }
        protected string ChangedBy { get; set; }
    }
}


We can now use this base type for all our domain objects. The following sample is taking from a simple airline booking system…


using System;
using System.Security.Principal;
namespace BloggSamples.Layers.Domain
{
    public class Flight : DomainBaseType
    {
        string _flightNumber;
        // constructor
        public Flight(string flightNumber)
        {
            // If the creation fields are empty then this is a new domain object
            if (String.IsNullOrEmpty(CreatedBy) && CreationDate == null)
            {
                CreatedBy = WindowsIdentity.GetCurrent().Name;
                CreationDate = DateTime.Now;
            }
            _flightNumber = flightNumber;
        }
        public string FlightNumber
        {
            get { return _flightNumber; }
            set
            {
                _flightNumber = value;
                // if the current users name is different from the creators
                // then the user is changing an existing object
                if (WindowsIdentity.GetCurrent().Name != CreatedBy)
                {
                    ChangedBy = WindowsIdentity.GetCurrent().Name;
                    ChangedDate = DateTime.Now;
                }
            }
        }
    }
}



Put very simply, when the Flight object is created you check the “CreatedBy” and “CreatedDate” fields. If these are already populated (the object may have been pulled out of the database, or a Registry or Identity Map) then we leave those values as they are. If they are empty, then this is a shiny new object and we populate the CreatedBy field with the current Windows user and the date with the current date. When the value of “FlightNumber” is changed, we check if the current user is thte same as the creator of the object. If not, then the user is editing an existing object.


The “Concerns” are described by the common functionality in the layer supertype. So, in my example, the “Concern” is the ability to perform an audit on each object in the domain (presumably for business purposes). You could say that wherever you can describe a common set of features like this, then you can abstract those objects into a layer.

Are then any Disadvantsges with a Layered Architecture?

Suppose you add a new mandatory field to your database that must be populated by the user. You must then make changes through each of the layers (Data, Domain, UI, etc…) to accept the user value and pass it down the stack to the data persistence layer. You would have to do this each time you made changes at the bottom of the stack. So there is a small but significan overhead with layering.

Advertisements

0 Responses to “Layers – Separating Software Concerns”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: