Wednesday, August 26, 2015

CSS Tips and Tricks: Make an image appearing as disabled.

At times, in your HTML pages, you would want user to display images as disabled.
For example, consider a Delete button in an HTML table where for a few rows you cannot allow delete operations (based on some criteria). In such cases, it would be a good (and self-explanatory) to display Delete image as disabled (instead of hiding the same). Following is the CSS for the same:

.disabledImage {
    opacity: 0.4;
    filter: alpha(opacity=30); /* msie */
}

Example usage:

<img src="../content/images/delete.png" title="cannot delete this entry due to dependency" class="disabledImage"/>

Thursday, August 13, 2015

Strategy Design Pattern - Explained with a real world example (C#)

Strategy Pattern is a Behavioral pattern.

In theory, the Strategy Pattern means - 
A family of algorithms, encapsulates each one, and make them interchangeable.
Strategy lets the algorithm vary independently from the clients that use it.

How do we elaborate it? or what can be a practical example of this?

Let us consider, we are creating a basic simulator for the mobile handset. A user (client application) selects a handset, and should be able to function whatever is supported in the handset.




As we all know there can be different types of mobile devices. Old (and cheapest) devices just support Call and SMS functionalities, and there is a range of smart phones/ new handsets which supports cool hardware and features like, rear camera (i.e., main camera), or front camera (i.e., the camera to take your selfie!). There are number of features in the smartphones (much more than camera), but to make the article a bit simple, we will only focus on following four features:
- Phone Call
- SMS
- Front Camera
- Rear Camera

We are taking example of two different handsets:
1. Nokia 5510 - having only basic features (i.e., phone call and SMS)
2. Nokia Lumia 920 - having tons of cool features (but for our case, its only Front Camera and Rear Camera that matters!)
3. Nokia 6600 - having only rear camera (sorry, but there was no facility to take a selfie with this 10 year old handsets!)

In Object-oriented world these three classes are called as "concrete implementations". So in future we should be able to add a number of handset, and so a concrete class for each of them.

Step 1 Identify the behavior(s) which are common across all the clients.
This means, there is a need of an abstract class containing the behavior which is common across all devices. This will be a base class for all the handsets.
Remember, this abstract class is the heart of Strategy pattern. Means, it will contain (and capable to plug-in) everything to create different handsets and attach various behaviors to them. This class is referred to as "Strategy".

    public abstract class Handset
    {
        public abstract string Display();

        public string MakeACall(string destinationNumber)
        {
            return String.Format("Calling {0}", destinationNumber);
        }

        public string SendSms(string destinationNumber)
        {
            return String.Format("Sending SMS to {0}", destinationNumber);
        }
    }

Display() is an abstract method because all different handsets will have their own implementation of how they should appear.

MakeACall() and SendSms() are concrete methods because all devices should make a call or send an SMS in the same manner.

Step 2 Do something for what varies!
In our example, we have Camera features which are varying in different devices. That means, a few handsets supports both front and rear cameras, whereas a few supports only rear camera, and there are those old phones which doesn't have a camera at all.

Lets create an interface which any type of camera can inherit from:

    public interface IPhotographyDevice
    {
        string TakeSnap(string location);

        string RecordVideo(string location);

    }

And, then the two classes implementing this interface, each class for each type of camera (i.e. rear camera, and front camera)

A class implementing the interface for RearCamera:

    public class RearCamera : IPhotographyDevice
    {
        public int megaPixels { get; set; }

        public RearCamera(int supportedMegaPixels)
        {
            megaPixels = supportedMegaPixels;
        }

        public string TakeSnap(string location)
        {
            return String.Format("Taking Photograph on {0} MP main camera", megaPixels.ToString());
        }

        public string RecordVideo(string location)
        {
            return String.Format("Recording Video on {0} MP main camera", megaPixels.ToString());
        }

    }

So you can see that we have encapsulated the photography features in their concrete implementations (i.e., FrontCamera and RearCamera).

Step 3 Integrating the behavior(s) which vary.
The abstract class should now delegate the photography related behavior to IPhotography interface.
For that, we need to inform the Handset class about IPhotography interface, so all the concrete classes of handsets inheriting from Handset class can use photography features,if they need to support them. (i.e., taking photos, and record videos through Front and/ or Rear cameras).

Handset class revisited to add an instance variable
    public abstract class Handset
    {
........
        public IPhotographyDevice photographyDevice;


    }

Step 4 Implement the methods for the new behavior
Handset class revisited to add TakeSnap and RecordVideo methods which calls relevant methods from concrete photography classes, if supported by the handset.
 public abstract class Handset
    {
....
        public string TakeSnap(string location)
        {
            if (photographyDevice != null)
            {
                return photographyDevice.TakeSnap(location);
            }
            else
            {
                return @"Sorry! this phone doesn't support photography";
            }
        }

        public string RecordVideo(string location)
        {
            if (photographyDevice != null)
            {
                return photographyDevice.RecordVideo(location);
            }
            else
            {
                return @"Sorry! this phone doesn't support videography";
            }
        }

    }

Step 5 Setting behavior dynamically
Our application allow users to change the camera run-time. Notice the "Activate Front Camera" and "Activate Rear Camera" buttons in the screenshot.
Here is the beauty of Strategy pattern wherein you can change the behavior dynamically (run-time polymorphism, as they say!)

Handset class revisited to add a setter method (i.e. a method that sets an instance variable - in our case, it is "photographyDevice"

public abstract class Handset
    {
.......
        public void SetPhotographyDevice(IPhotographyDevice newPhotographyDevice)
        {
            photographyDevice = newPhotographyDevice;
        }
........
    }

Step 6 Implement concrete classes from the Strategy
Now we have our Strategy (i.e. Handset abstract class) is ready, its time to create concrete classes.

public class Nokia5510: Handset
    {
        public override string Display()
        {
            return "This is a very basic model from Nokia with no camera whatsoever!!";
        }
    }
This particular device doesn't support any sort of camera, and so we don't need to set the instance of "IPhotography" variable.
when your application will try to execute any photography related methods (i.e. TakeSnap or RecordVideo) then it will say, the phone doesn't support these features)

public class NokiaLumia920 : Handset
    {
        private readonly int rearCameraMPs = 12;
        private readonly int frontCameraMPs = 5;        

        public NokiaLumia920()
        {
            photographyDevice = new MainCamera(mainCameraMPs);
        }

        public void LoadFrontCamera()
        {
            SetPhotographyDevice(new FrontCamera(frontCameraMPs));
        }

        public void LoadRearCamera()
        {
            SetPhotographyDevice(new RearCamera(rearCameraMPs));
        }
        
        public override string Display()
        {
            return "Nokia Lumia 920... A full-featured phone from Nokia";
        }
    } 
This device supports both front and rear cameras, and the client application can switch the cameras at run-time, by calling "LoadFrontCamera" and "LoadRearCamera" methods which internally calls a setter property to change the behavior. That means, we initially attach the behavior (through constructor), and then change it.

public class Nokia6600 : Handset
    {
        private readonly int rearCameraMPs = 12;

        public Nokia6600()
        {
            photographyDevice = new RearCamera(mainCameraMPs);
        }

        public void LoadFrontCamera()
        {
            //Front-camera are not supported in this device
            SetPhotographyDevice(null);
        }

        public void LoadRearCamera()
        {
            SetPhotographyDevice(new RearCamera(mainCameraMPs));
        }

        public override string Display()
        {
            return "Nokia Lumia 6600... A Nokia phone with a lots of features and a high-resolution camera";
        }

    }

This device supports only rear camera, and so when your application tries to attach front camera, the instance is assigned to a null value. A client application can again start the rear camera by invoking "LoadRearCamera".

Step 7 Code the simulator
By now we have the "Strategy" (i.e. our Handset abstract class), interfaces and their concrete implementations, and concrete handset classes are ready. Now its just a matter of instantiate the handset classes (based on the selected handset in drop-down) and invoking methods in various events of simulator.

Call me lazy :) but I am leaving this to the readers to implement this simulator. Feel free to comment in case if you face any difficulties.

Summary
To summarize and conclude, we have used "Strategy design pattern" in our Mobile Handset simulator application, and following are the benefits:
- Behaviors can be added run-time
- Behaviors can be switched run-time
- Any new implementation of a behavior will not require any change in the "Strategy" class.
- There is a single class (called as Strategy) that contains everything which is required by the clients. (abstract methods, concrete methods, instance variables of Interface type for the behavior and setter methods to change the behavior at run-time)
- If there is a need to supporting any new device in the simulator, and if that device has possible features within call, sms, and camera, then its just a matter of adding a new concrete class for the handset as we have done.
- If the new handsets are supporting a different type of camera (may be, a "spy camera"), then you will just need to create a new concrete type from "IPhotographyDevice", and you should be able to use the "Spy camera" in your simulator straight-away. And similarly, can switch between - front, rear and spy cameras similar to what we did in our example. 
- if the new handsets are supporting some new behaviors, then a new interface for the behavior will need to be added, and so its concrete application (as per step 2). After that the "Strategy" class will need to be integrate that behavior (steps - 3,4,5). And phew, you are ready to use this new behavior.


Hope this article helped you in understanding Strategy pattern. Feel free to ask any questions, or provide feedback!