Posts Tagged seperation of concerns

SOLID conclusions with ISP and DIP

In my last post we went over LSP ( Liskov Substitution principle ) , how it helps achieve Subtype Polymorphism. We learnt how to think in terms of client programs and how client’s call to  programs can influence the quality and design of applications. The SRP and OCP are foundational principles on which LSP and the next one we discuss today , ISP manifest themselves.  It is not enough if Single Responsibility and Open Closed are understood – the rest of the three principles are where you see their applications and extensions. LSP , ISP and DIP all three teach us how to design from a client’s point of view. Uncle Bob calls it as “Clients exerting forces “  . 

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use

ISP helps formulate mechanisms on how interfaces should be segregated so the same interface can be useful to different clients. It’s a very powerful thought that can bring strong results. Single Responsibility talks about writing interfaces that have very cohesive functions . ISP takes it one step further and gives concrete ideas that give rise to reusable interfaces . This is where the relationship and the difference between SRP and ISP exists .

So how does ‘Segregating’ Interfaces help the clients ? Interfaces are meant to represent a certain type of behavior to the client and by virtue of their contractual representation promote pluggability. So when interfaces represent more than one type of behavior , they provide more than what a client needs . This leads to the interface becoming incapable of being used for plug-in purposes. Also they become ‘Fat’ in nature , with unncessary behavious not useful in the client’s context. Basically this is solidifying more on the SRP and OCP and stressing a whole lot more on how interface contracts should represent one type of behavior. Almost all patterns have a basis in SRP , OCP and ISP. Let’s say we are writing a class to represent a Persistence Medium. One of the most popular persistence medium is Database . So is XML . And a lot of applications use simple JSON files to store simple content.  Say , we start out by writing a PersistenceMedium class. So a simpe IPersistenceMedium looks like this :

Code is pseudo only , to describe the principle , not a working , compiled example :

// IResult is an imaginary interface 

interface IPersistenceMedium
{
       string fileName { get; set; }
       string connectionString { get; set; }

       void Open();       
       void IResult ExecuteQuery(string query);
       void IResult ReadFile();
       void Close();
}

//So our database class can be written like this:

public class Database : IPersistenceMedium
{
    private string _connectionString;

    public string connectionString
    {   get{ return _connectionString; }  
        set{ _connectionString = value; }    
    }

    public void Open(){  /* database open connection code */ }
    public IResult ExecuteQuery( string query );
    public void Close(){  /* database close connection code */ }
}

// The JSONStore can be written like this :

public class JSONStore : IPersistenceMedium
{
     private string _fileName;

     public string fileName
     {   get{ return _fileName; }  
         set{ _fileName = value; }    
     }

      public void Open(){  /* open a JSON file code */}
      public IResult ReadFile();
      public void Close(){  /* close file code  */}
}

See what happened above ? The Database class could not use ReadFile() and fileName and JSONStore could not use ExecuteQuery() and connectionString . Although both are variants of a PersistenceMedium behaviour , they are unnecessarily clubbed together from the perspective of Database and JSONStore classes which are the clients of IPersistenceMedium.

A Better way would be :

interface IFileConnection 
{ 
     string fileName { get; set; }
     void Open();
     void Close();
}

interface IDatabaseConnection 
{   
      string connectionString {  get ; set; }   
      void Open();
      void Close();
}

interface IDBOperation
{
     IResult ExcecuteQuery();
}

interface IFileOperation
{
      IResult ReadFile();
}

Now this provides interfaces that can be specifically used for Database or JSONStore because we segregated them keeping in mind different clients / client groups. The interfaces which can be used for JSONStore can be used for XML or any other type of file store. Similarly the interfaces that got written for Database can be used for any type of database , SQL , Oracle or NoSQL . The interface is less fat , with interfaces ‘Segregated’ strictly based on different client usages . This is SRP in effect, by using ISP.  What are the different ways of using these with the Clients ? One obvious way is multiple inheritance.

public class JSONStore : IFileConnection , IFileOperation
{
    private string _fileName;
    public string fileName
    {   get{ return _fileName; }  
        set{ _fileName = value; }    
    }

    public void Open(){ /* open file*/ }
    public IResult ReadFile(){ /* Read File */}
    public void Close() { /* Close File */ }

}

public class Database : IDatabaseConnection , IDatabaseOperation
{
    private string _connectionString;
    public string connectionString
    {   get{ return _connectionString; }  
        set{ _connectionString = value; }    
    }

    public void  Open() { /* Open Connection */}
    public IResult ExecuteQuery(){  /* execute query to obtain results */}
    public void Close(){ /* Close Connection */}

}

The above JSONStore could be very well be written as FileStore , in that case different FileStores can be used and IResult representing different result types form different types of files.

There are different ways to implement the above without multiple inheritance. One way is to use something like a Strategy pattern where IFileOperation has concrete classes for JsonFileOperation and XmlFileOperation – because each may have subtle read differences. XML requires special parsing and JSON is more of a string representation.

We have been able to establish in many different ways the value of SOLID – how it  leads to good design practices and understanding of patterns.

I will conclude without diving into Dependency Inversion – there are fantastic blogs including Uncle Bob’s report. Dependency Inversion distinguishes itself by establishing how layers should interact  without depending on each other. Again a powerful concept that has led to great programming practices including Test Driven Development and several patterns that facilitate the principle. SOLID is definitely worth your time !

, , , , ,

1 Comment

Way to Patterns : even more SOLID

In the last post we saw how OCP facilitates extensibility and reusability . OCP is the foundation on which several patterns have been written. The Strategy pattern is a great example of OCP where subclasses are written based on different algorithms. The manifestation of OCP happens in the third SOLID principle , the ‘L’ as we know ,  Liskov Substituion principle – perhaps the more involved and less understood principles in SOLID .

We saw how SRP can lead to OCP – LSP takes OCP and establishes clear rules that will ensure polymorphism is accomplished correctly. LSP attempts to achieve what we call subtype polymorphism through it’s rules. In short we can represent this in pseudocode – a client call to a subtype method call , through a base class interface:

public class Supertype{   public virtual outparam SomeMethod( inparam );   }     
public class Subtype : Supertype { public override outparam SomeMethod( inparam );  } 

 //Client call:   
 Supertype baseType = new Subtype();    
 outparam = baseType.SomeMethod(inparam);

Liskov Substitution statement  translates to : Subtype(derived type) must be behaviorally equal to their base types. They must be usable through the base type interface without the need for the user to know the difference.

LSP needs to be understood from a client’s perspective . Client here means : Calling programs , Users of your interfaces and abstract classes within the organization  or outside the organization. A Client perceives the behavior of a class through methods of a class : arguments passed , value returned and any state changes after the method execution. So basically to be able to use a subclass / subtype in place of a superclass/supertype the sub type successfully needs to preserve argument requirements and return expectations by the client.  A client code that gets written keeping in mind the Supertype to call it’s method should not change or break when replaced with subclass method calls . Compilers do enforce Signature compliance when methods are overridden from abstract classes . However internally within the implementation if arguments or return values were treated in a manner that could break the client code , the code is in violation of LSP because essentially the contract with the client was broken . Compilers typically will not catch these violations.

It is the programmers responsibility to ensure LSP compliance for the most part.  In order for the internal subtype behavior to keep in consistency with supertype behavior , these principles were formed.

There is a very subtle and interesting nuance that one needs to understand here. You could very well write a ‘Superclass’ , and then write a ‘Subclass’ – override the Superclass method to give a specific implementation. Use the subclass in your programs to execute the subclass specific method. You may never see anything wrong up until you expect the subclass to be a ‘subtype’ of the Superclass which is a Supertype. It’s when a ‘subclass’ is expected to become a ‘subtype’ is when LSP comes into play.

A lot of blogs have been written to explain these rules.  I have cited at the end some good ones in order to understand them with code examples : instead in this blog let’s try and understand some of the confusing rules that mostly I have seen people asking questions about .  Let’s just list all of them first :

  • Contravariance of method arguments in the subtype.
  • Covariance of return types in the subtype.
  • No new exceptions should be thrown, unless the exceptions are subtypes of exceptions thrown by the parent.
  • Preconditions cannot be strengthened in the subtype
  • Postconditions cannot be weakened in the subtype
  • Invariants must be preserved in the subtype.
  • History Constraint – the subtype must not be mutable in a way the supertype wasn’t.

Now, let’s take just the two which seem to confuse most people :

  • Preconditions cannot be strengthened in the subtype.
  • Postconditions cannot be weakened in the subtype.

Preconditions apply to arguments which will be used as part of the implmentation. Postconditions mostly relate to return values or the state after the implementation is executed. Preconditions are requirements on users of the functions, while postconditions are requirements on the functions themselves. Preconditions get executed before the actual implementation is executed , whereas postconditions are executed after.

Preconditions cannot be strengthened in the subtype.

Wikipedia explains this as :

In the presence of inheritance, the routines inherited by descendant classes (subclasses) do so with their preconditions in force. This means that any implementations or redefinitions of inherited routines also have to be written to comply with their inherited contract. Preconditions can be modified in redefined routines, but they may only be weakened. That is, the redefined routine may lessen the obligation of the client, but not increase it.

What is the obligation of the client ?  The arguments that need to be passed  , is the obligation of the client. If the preconditions  are set in such a way in the subclass method  that the choice of the arguments which can be passed from the client is lesser or restricted then you actually strengthened the precondition .  This increases the obligation of the client.

Let’s understand this with an example. We will modify the IFormatter interface from the last post to an abstract base class with some implementation.

 abstract class Formatter{            

         public virtual string Format( String message)
         {
                if ( String.IsNullOrEmpty( message ) ) 
                    throw new  Exception ();
                // do formatting
         }      

     }
    // strengthened precondition
    public class MobileFormatter : Formatter{

         public override string Format( String message)
         {
                if ( String.IsNullOrEmpty( message ) || message.Length > 250  ) 
                    throw new  Exception ();
                // do formatting
         }

    }
    // weakened precondition
    public class MobileFormatter : Formatter
    {
        public override string Format(String message)
         {
                if ( message == null  ) 
                   throw new  Exception ();
                // do formatting
         }

    }

As we see above the MobileFormatter placed more restriction on the arguments in the strengthened precondition – this will force the client to change their code to accommodate for this if they want to avoid getting an exception.  So behaviorally the base and subtype are different.

In the weakened precondition what happened is that the client now does not need to accommodate the code for MobileFormatter, the argument that gets passed to MobileFormatter , works for base Formatter as well because the validation in Formatter is stronger or the validation in MobileFormatter is weaker.

Postconditions cannot be weakened in the subtype.

Wikipedia explains this as :

In the presence of inheritance, the routines inherited by descendant classes (subclasses) do so with their contracts, that is their preconditions and postconditions, in force. This means that any implementations or redefinitions of inherited routines also have to be written to comply with their inherited contract. Postconditions can be modified in redefined routines, but they may only be strengthened. That is, the redefined routine may increase the benefits it provides to the client, but may not decrease those benefits.

Let’s understand this with a code example:

   abstract class Formatter
    {

        public virtual string Format(String message)
        {

            // do formatting
            return message.Trim();
        }

    }
    // weakened postcondition
    public class MobileFormatter : Formatter{

         public override string Format( String message)
         {

                //do formatting
             return message;
         }

    }
    // strengthened postcondition
    public class MobileFormatter : Formatter
    {
        public override string Format(String message)
        {

            //do formatting
            return message.Trim().PadLeft(5);
        }
    }

What we see above in the MobileFormatter is that the postcondition got weakened by removing the Trim method. This provides the client less than what was provided in terms of the result .

Then to correct it , we strengthened the postcondition by adding left padding. This does not require the client to change any code , however the code gets the extra benefit of padding. The above example is rather crude but serves the purpose of explaining .

There is a very interesting pattern called Template pattern accomplishes LSP via template methods written inside a base class which are overridden in derived classes.  For now , this is enough to contemplate about – more in the next blog .

Here are some really good blogs on Liskov that discuss other rules as well:

http://www.ckode.dk/programming/solid-principles-part-3-liskovs-substitution-principle/#contravariance

http://msdn.microsoft.com/en-us/magazine/hh288081.aspx

Until then happy programming !

, , , , , ,

1 Comment

ASP.Net MVC : coming up to speed

In my last blog post I talked about how I chanced upon ASP.Net  MVC at my last project and my thoughts on whether a development group should consider it as a design choice for their future projects. In fact few months have passed since I wrote the last blog post, and ASP.Net MVC has taken another leap with MVC 3. From Microsoft’s side there is big push of course and I do see a lot of adoption from development groups in different organizations. There is a learning curve that I see most groups are going through and it can be hard or easy depending on the background that you come from your previous development tasks.

The best way to get started with ASP.Net MVC is if you already are not familiar with MVC as a pattern, familiarize yourself with it.  There are several websites that discuss it as a pattern : in the pattern world, it’s more of a ‘framework pattern’ as opposed to a ‘basic pattern’ from the Gang of Four patterns. So based on your level of understanding of patterns, start with Basic patterns aka Gof4 and then understand it as an aggregate pattern of different basic patterns. MVC itself is acheived by different pattern proponents and architects as an aggregate of different types of patterns: like in Head First Design Patterns book, the authors acheive MVC by combining the Observer , Strategy and the Composite pattern.  You will observe after your readings that several implementations of MVC are a strong use case of Observer pattern where Views subscribe to changes in the Model – also of Composite patten for the View itself.  In the web model though , the use case of Observer pattern may not exist due to the stateless nature of the View. So ASP.Net MVC is one variation of the basic MVC pattern adapted to web paradigm.

It’s the most important step to get as clear an understanding of MVC under the hood from a patterns perspective: this gives a you a much clearer perception of Model, Controller and View , their interaction. You could jump start into it by creating a “Hello World” application in Visual Studio 2008 , 2010 – however it will become very difficult as you go further in accomplishing all your programming functions because the underlying concepts are not clear, especially for those who are used to ASP.Net web forms programming.

Another important start is to pick up a good book , by now there is MVC 3 , however while I am writing this , few good books are out on MVC 2. The ones I read are books by Steve Sanderson and Jeffery Palermo , famous authors. Both are great books in their own regard: Sandeson’s book covers all basics extensively – so read that as your first basic book and Jeffery Palermo’s book covers several advanced topics , like dependency injection , different unit testing methods in a lot more detail. Both will go a long way in getting your foot in the ground , and being well prepared with your project work. I have listed at the end of the blog all the books I read to get up to speed and they helped me a lot. It is good to get few copies of books like this for the whole team and everybody reads it. Of course , there is ton of websites and without a doubt you should follow Scott Gu, Scott Hanselman, Phil Haack and Stack Overflow. The books combined with the websites will give you an understanding of the ASP.Net MVC framework which is written on top of MVC design pattern.

Another new concept that may get thrown at you with ASP.Net MVC is Routing , the ‘RESTful’ way of doing things – it’s undoubtedly a strong concept and you must be very familiar with it from day one. ‘REST’ is meant to be the way Web programming is done – as you progress you will see how important it is for you to be very clear on some concepts like the HTTP methods of GET and POST . WIKIPEDIA itself has some great information on REST , HTTP Methods etc.  As far as Routing itself is concerned the the two books I mentioned above do cover it extensively as to how to achieve it with ASP.Net MVC framework.

Here is a list of all the links for References:

Gang Of Four Patterns Book

Head First Design Patterns

Steve Sanderson’s MVC Pro Book

Jeffery Palermo’s MVC Book

Scott Guthrie

Scott Hanselman

Phil Haack

WIKIPEDIA On REST

Good Luck With MVC !

, , , , ,

Leave a comment

ASP.Net : To MVC or not to MVC ?

I was recently faced with a situation at work to execute a ASP.Net MVC project to release. The design choice was not mine , however due to certain constraints I was asked to finish it to deployment. We have released a 1.0 version of the project now and in retrospect , if I had started the design from scratch , would I have picked the ASP.Net MVC as opposed to WebForms  which is well established and mature ?. I probably would not have considering the proven rapid time to productivity of WebForms especially when we had several deadlines looming over our heads . However, having already a project with MVC in production I realize the merits of it enough to say, the decision to do it in MVC was not a bad one at all, although we had several pitfalls on the way. Will I use MVC for my next ASP.Net project ? Most probably , yes.

I am sure several shops are faced with this dilemma lately as far as starting a new ASP.Net project….MVC or not? As usual  ‘it depends’ on the context of your organization and it’s development practices so far , however if I were to make a Utopian decision on this problem I would say Yes, MVC is the right choice to get started with the project. This clearly states that MVC is a superior design pattern and ASP.Net MVC has more to offer that can go a long way with your company’s ASP.Net / web development strategy.

Typically I noticed that MVC is a natural choice for developers coming from Java world having to do ASP.Net …so is with Ruby On Rails developers. Microsoft surely succeeded in wooing the Java and ROR folks with their ASP.Net MVC strategy. For those of you who have been hardcore ‘WebFormers’ it’s undoubtedly worth your time because we all know that a complex project developed in WebForms can become a debug nightmare with PostBack and WebForm event life cycle. And there are several other shortcomings…ViewState , Testability , not being able to separate the concerns. A high level of competency in architecture is required in design of moderate to complex WebForms projects  demanding solid upfront design effort that can cost time and money.

Asp.Net MVC manages to alleviate a lot of these due to it’s inherent clear Separation Of Concerns thanks to MVC itself , a known pattern in the Software Architecture world. The framework itself does a lot of groundwork for you as long as you adhere to some good  programming practices as you go along your development cycle. Basically , you  jump start into a good design without having to put in a lot of work upfront. Right there I think , you gained cost and time.

So, to sum it up – for medium to large sized projects it’s undoubtedly a better choice. For smaller projects or prototypes where time-to-market or quick overview could be  the primary concern , Webforms is a better choice since it offers greater productivity. For larger projects , time-to-market is normally one of the concerns , however other predominant concerns are  maintainability , extensibility , testability and performance. All of this , MVC will address and  improve for your projects across the board.

The current ASP.Net MVC 2.0 system has it’s demerits as well, biggest one at this point being , it’s lack of maturity. Version 2 is out there, however it lacks the Rapid development components of WebForms like the Server controls. This can make developers frustrated several times since it slows you down to a great degree. However the brighter side is once you get a hang of how to use HtmlHelpers and enhance them you will appreciate the degree of control and customization it offers as opposed to server controls which could end up becoming sometimes black boxes in difficult situations. The web world is making progress out there with MVCContrib which offers some controls for MVC and Microsoft soon will be coming out with Version 3 which has a lot of enhancements along with a new View Engine called Razor.

There sure is a learning curve for most WebFormers  trying this framework for the first time , more so if you are not familiar with MVC design pattern. So, how do you get your team ready for this new seemingly ‘Rewarding’ technology in a seamless and streamlined fashion? It’s a huge paradigm shift and you want to make sure the team does it step by step without feeling bogged down by it.

In the next blog , I will give you my two cents of how I think the development team can go about learning this framework and making a transition to this technology.

, , , , ,

1 Comment