Tag: C#

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 !

MonoDroid : First impressions

Just like everyone , I have been bitten by the Handheld bug . Mobile Phones and tablets will definitely be the wave of the future and will influence the way we live and conduct business in a huge manner. Android

They already have started doing so , they are so much a part of us. I am excited about the whole tablet mania which I think will revolutionize the use of computers . As a result, I wanted to write some ‘apps’ as well, may be make some extra cash or start a business.

I started out thinking iPhone and iPad , however soon realized that I would have to own a Mac computer to do development on these because I did not come across a good development environment on Windows for iPad or iPhone . ‘MonoTouch’ by Novell was closest to the development technologies I am most familiar with , however MonoDevelop and MonoTouch also are required to be used on a Mac. Hence I decided to go the Android way – which allowed programming easily on Windows… and once again a very promising Mobile OS , thought this would be my best middle ground.

C# and .Net being my strongest technology stacks , I decided on trying MonoDroid by Novell so I could use Visual Studio 2010 and C# to do Android programming. I had choice of Java and Eclipse as well, which I have installed parallely along with Android SDK just for comparison’s sake. I thought if MonoDroid works I am better off with it since it gives me a chance to program in C# and .Net , chances are very good I’ll save time in learning nuances of Java which I left behind a few years ago. Having said that I did try the ‘Hello World’ program with Java and Eclipse , ran the application successfully on the Android emulator.

MonoDroid gave me a similar experience as Java in terms of installation and running of the simple “Hello World” program. The installation of MonoDroid required an extra installation of MonoDroid SDK.. other than installing Java SDK , Android SDK , ADT Plugin and the Development environment which is VS 2010 in .Net . All you need to do is follow the instructions in the order they are supposed to be installed in , everything goes smoothly. I was also able to run the “Hello World” program with MonoDroid in the Android Emulator. So far so good. I started getting deeper with this encouragement , thought I’ll try different things like reading XML data and displaying in a ListView or GridView. I also tried things like reading from the existing databases like the Contacts database from the Device and printing some Contact names on the screen.

I think MonoDroid is a very good start in Android development , their 1.1 version released as of this writing . They have done a good job of creating C# and .Net object wrappers around Android SDK – which makes it very easy to look up different objects and methods within the MonoDroid API in correlation with Android API.  For example ‘ContentResolver’ as in Android API is named the same way in MonoDroid API and so are the corresponding methods. However the debugging with a breakpoint in the code does not always work – I am so used to examining the objects in runtime to learn more about them or fix some runtime bugs – it was very frustrating at times without understanding why the debugging did not work. I raised this in the MonoDroid forums on MonoDroid site and they said that they are trying to fix the debugging issues in the next release.

They have done a good job of creating C# and .Net object wrappers around Android SDK – which makes it very easy to look up different objects and methods within the MonoDroid API in correlation with Android API.

Another issue I ran into was that while going through several iterations of development I was constantly making small changes and redeploying. The modified binary would not get redeployed right away after hitting F5 or clicking ‘Start Debugging’ . Again it was creating road blocks while making changes and wanting to see them right away . I learnt later that “the new binary isn’t deployed immediately because it can’t; the only way to update the app is to build a new package (.apk) and install the new package (plus an intermediate package uninstall). Package creation is not an instance process, hence the delay. MonoDroid group said that they intend to improve the package creation experience in the future, but there’s only so much that can be done…” .

So, all in all it was a mixed experience with being able to start very well to hit some high points and some low points. It does get a little frustrating with not too many examples on the web or documentation – there are few programmers who are fairly actively making posts on MonoDroid but you are a lot on your own . One of the things I started doing was first copy code example from Android API and then convert them to .Net code using the IntelliSense . That helped in terms of at least getting the code to a point where it looked right syntactically and ready to run. There is a steep learning curve in understanding Android API – which can take a few weeks depending on how much time you have in your hands.

MonoDroid is definitely a step in the positive direction attracting .Net developers quickly into Android programming – however the development experience still needs to improve . I am not sure if it’s ready for real world deployment applications because I have not yet seen any Show Cases of MonoDroid real world Apps unlike MonoTouch which a lot of people have already used to develop Commercial applications selling in the market. However if you want to do Android programming and want to stick to .Net technologies , I am sure with a little more wait it would be worth it , considering Mono’s reputation. MonoDroid will soon be upto where MonoTouch already is. Give it a try and experience for yourself by starting from here.