SOLID : Liskov Substitution Principle (Part 1)

The “L” in SOLID stands for Liskov Substitution Principle, named after Barbara Liskov, who initially introduced in 1987 keynote address. LSP provides guidelines for creating inheritence heirachy where a client can use any class or subclass without breaking the expected behavior.

We will begin by looking at the official definition first.

If S is a subtype of T, then objects of type T may be replaced with objects of type S,without breaking the program.

It would be unwise to explain this theoratically, hence like always, let hit the Visual Studio and write some code. I would like borrow an example given by Tim Correy in his famous video.

Assume we have an Employee class defined as follows.

public class Employee
{
public string Name{get;set;}
public Employee AssignedManager{get;protected set;}
public virtual double GetPay()
{
var currentSalary = 500;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

public virtual void AssignManager(Employee manager)
{
Console.WriteLine("Manager Assigned");
AssignedManager = manager;
}
}

Now let’s assume we have a Manager class, which inherits from Employee

public class Manager:Employee
{
public override double GetPay()
{
var currentSalary = 750;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

public override void AssignManager(Employee manager)
{
Console.WriteLine("Manager Assigned");
AssignedManager = manager;
}
}

Let’s write some client code now which consumes these classes.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new Employee();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

Output

Current Pay 750
Current Pay 500
Manager Assigned

As you can observe, the output is perfectly fine. Let us try making some changes to the Client Code now. Let us replace the Employee class (programmer instance) with Manager.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new Manager();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

Output

Current Pay 750
Current Pay 750
Manager Assigned

This has turned out fine as well. Yes the output is different, which is expected considering the Pay for Manager and Employee are different, but the client hasn’t behaved unexpectedly. Let’s write one more class, inheriting from Employee and call it CEO.

public class CEO:Employee
{
public override double GetPay()
{
var currentSalary = 750;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

public override void AssignManager(Employee manager)
{
throw new Exception("Am the CEO, no Manager for me !!");
}
}

The difference this time is of course the CEO doesn’t have a Manager and it raises an exception in the AssignManager method. Let’s head back to out Client code and replace Employee with CEO in our original code.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new CEO();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

Output

Exception:Am the CEO, no Manager for me !!

Aha, we have an exception here. When replaced the Employee (Base type) with a subtype (CEO), the expected behavior of program has been broken. This is a violation of LSP.

Let’s examine the violation further. It is often said that Inheritence is the IS-A relation. However, if you truely examine CEO and Employee, do they follow a IS-A relation in every sense ? Not really, not according the current definition of Employee. Yes, that is right. The problem doesn’t quite lie in CEO, but it originate from the definition of Employee class. While designing the Employee class, we “assumed” that all Employees would have a manager.

So what is the best solution for this scenario ? What if we were to ensure the Employee class had only those functionalities which are common to every employee ? Obviously, the Manager is not applicable for everyone, so let’s remove it and create an interface which contains only the basic employee functionalities.

public interface IBaseEmployee
{
string Name{get;set;}
double GetPay();
}

public abstract class BaseEmployee:IBaseEmployee
{
public string Name{get;set;}
public virtual double GetPay(){ return 0;}
}

Remember, we still have to consider the Manager assignment. What we would do here is define another interface IHasManager, which would wrap the functionalities required for Employees who has Manager.

public interface IHasManager
{
IBaseEmployee AssignedManager{get;set;}
void AssignManager(IBaseEmployee manager);
}

Let’s now define our Employee and Manager classes.

public class Employee:BaseEmployee,IHasManager
{
public IBaseEmployee AssignedManager{get; set;}
public override double GetPay()
{
var currentSalary = 500;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

public virtual void AssignManager(IBaseEmployee manager)
{
Console.WriteLine("Manager Assigned");
AssignedManager = manager;
}

}

public class Manager:BaseEmployee,IHasManager
{
public IBaseEmployee AssignedManager{get; set;}
public override double GetPay()
{
var currentSalary = 750;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

public void AssignManager(IBaseEmployee manager)
{
Console.WriteLine("Manager Assigned");
AssignedManager = manager;
}
}

As you can see, the Manager and Employee inherits from BaseEmployee and implements the IHasManager interface. The next step is to define our CEO Class, and this time, we know that he doesn’t need a Manager.

public class CEO:BaseEmployee
{

public override double GetPay()
{
var currentSalary = 750;
Console.WriteLine($"Current Pay {currentSalary}");
return currentSalary;
}

}

That’s it. Let’s rewrite our Client code now.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new Employee();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

The above code compiles and executes as expected. Let’s replace the Employee with a Manager first.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new Manager();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

That works fine as well. Let’s try again, and this time replace with CEO.

var manager = new Manager();
manager.Name = "John Doe";
manager.GetPay();

var programmer = new CEO();
programmer.Name = "Roel Doel";
programmer.GetPay();
programmer.AssignManager(manager);

Not surprisingly, that doesn’t compile at all. CEO doesn’t have the AssignManager method as it doesn’t implement the IHasManager interface. Your client no longer have unexpected behavior as such errors are caught during compilation.

That was pretty easy, isn’t it ? But we are not done yet. There is more to the definition of LSP. In the next part of this series, we will examine the Contact and Variance rules which must be followed for LSP compliance.

Evil Code #009 : nameof Operator

The nameof() operator has been so commonly used by the developers that one could not be called guilty if he assumes it was there since C# was born. Despite that, there are days it might still surprise you.

What would be your reply if I asked you to predict the output of the following.

nameof(School.Division.Student)

No prizes for guessing. It wouldn’t be hard to guess that the output would be “Student”. So what is the surprise factor.

Let me add some more constraint to the code. What could be the output is the code was compiled on Visual Studio 2017, v15.5.x ? Would your answer change ?

If you were to say that you answer would still be the same, then here is the surprise for you. This is a bug on the C# compiler, which results in compiler error when you use nested properties /sub expression of the format X.Y.Z.

CS0120: An object reference is required for the non-static field, method, or property 'C.Instance'

This bug was fixed in 15.7.x, and anyone using a Visual Studio with version 15.7.x or above, would be able to see the desired result of “Student”.

If you are one of those lucky ones as yours truely, then you are in for an unusual compiler error. If you are interested to read more on the issue, please follow the issue on Github here.

GOF: Composite Pattern

Composite Pattern, in a way, literally takes of from where Decorator Pattern ends. One might be inclined to think of it as a specialized case of Decorator Pattern which composes one or more instances of similiar objects and manipulate them uniformly. This allows the client to work on a single entity or composition of entity uniformily, or in other words, it eliminates the need of programmers to discriminate between leaf and branch, and thereby avoid writing specific logic to handle both scenarios.

The key components of Composite Pattern can be defined as follows

Component
Components defines the interface that specifies the behavior that needs to be uniformly executed by primitive object or composite object.

Leaf
The non-decomposible leaf object, which defines the behavior for the primitive object

Composite
Holds the collection of Child components, and implements the behavior of components that have children.

That would be enough of theory, let’s write some code now. For the sake of example, we will write a little program that would print the size of given File/Directory. Let’s begin by defining the Component interface.

public interface IMetaInfo
{
double GetSize();
}

The next step would be define the behavior of the primitive object, which in this case would be the File.

public class FileObject : IMetaInfo
{
private string _fileName;
public FileObject(string fileName)
{
_fileName = fileName;
}
public double GetSize()
{
Console.WriteLine($"Calculating size of {_fileName}");
return 0;
}
}

As one can understand, the actual behavior is different for File and Directory. The size of Directory needs to be cumiliative size of all the individual Files in it. Let’s define the behavior for Directory Class now.

public class DirectoryObject : IMetaInfo
{
private string _directoryName;
private List<IMetaInfo> _fileCollection;
public DirectoryObject(string directoryName)
{
_directoryName = directoryName;
_fileCollection = new List<IMetaInfo>();
}

public void Add(IMetaInfo file)
{
_fileCollection.Add(file);
}

public void Remove(IMetaInfo file)
{
_fileCollection.Remove(file);
}
public double GetSize()
{
var directorySize = 0d;
foreach (var file in _fileCollection)
{
directorySize += file.GetSize();
}
return directorySize;
}
}

As one could see in the example code, the Directory Structure uses the bahavior of the individual File Structure to calculate the cumiliative Size. Let’s write the code for Client now and see how client can work without having the knowledge of what exactly it is dealing with.

class Client
{
static void Main(string[] args)
{
Console.WriteLine("When using Composite Object");
var directoryInstance = new DirectoryObject("BaseDirectyory");
for(var i = 0; i < 10; i++)
{
directoryInstance.Add(new FileObject($"{i.ToString()}_File"));
}

GetSize(directoryInstance);

Console.WriteLine("When using Component Object");
var fileInstance = new FileObject("Another File Instance");
GetSize(fileInstance);
Console.ReadLine();
}

private static void GetSize(IMetaInfo instance)
{
instance.GetSize();
}
}

The Client.GetSize() method accepts an instance of IMetaInfo as the parameter. It doesn’t really know whether it is actually dealing with a Composite object or a Primitive one.

The Composite pattern is a highly useful pattern when one needs to deal with a irregular structure of objects and composite of objects, enabling the client to deal with them uniformly.

The entire source code shown in this example are available in my GitHub.

3 Rules for TDD

I couldn’t help but share this. There couldn’t be a better way to summarize the unwritten rules of TDD, than the one wrote by Uncle Bob in his famous book ‘Agile Principles, Patterns and Practices in C#”.

  • Don’t write any production code until you have written a failing unit test.
  • Don’t write more of a unit test than is sufficient to fail or fail to compile.
  • Don’t write any more production code than is sufficient to pass the failing test.

What it emphasises is when to switch between writing Unit Test and Production code, a key point, atleast according to me, for many times I see developers who try to think and build way too many test cases than what is actually needed. Honestly, yours truly too has been guilty of so called BDUF for Unit Test.

Uncle Bob, in formulating the 3 basic rules, emphasis that one needn’t write a unit test no more than when it fails or fails to compile, after which the developer proceeds to write the minimum code required to pass the test case. This short cycles would help the developer adopt the TDD approach in a better way.

Thanks Uncle Bob.

Revisting Anonymous Type

While classes and structs are extremely powerful, there are times when you want to escape the cermonies they require even for simplest of design. This is where anonymous types comes handy and has been so frequent used by the developers.

So what are Anonymous types really ? Let’s consider an example first.

var point = new {X = 20, Y = 30}

Anonymous Types are compiler generated immutable reference type.

Though framed in few words, that definition probably describes a lot more than that meets the eye. From the point of definition of our anonymous type above, it means you are directing the compiler to generate an internal sealed class, which has two read-only properties namely X and Y. For example, the compiler might generate something similiar to following class for the anonymous type we just declared.

internal sealed class Point
{
private int _x;
private int _y;

public int X => _x;
public int Y => _y;

public Point(int x,int y)
{
_x = x;
_y = y;
}
}

Do notice this might not be exactly what compiler generates. There could be certain things which you cannot do yourself, but the above example kind of provides the gist.

The Anonymous Type syntax allows you to do all that declaration with very little need to type them yourself. This eliminates the chances of human error, in addition to saving your time as well as polluting the application namespace. The scope of the defined anonymous type is restricted to the method it is defined.

But, Anonymous Types has their drawbacks as well. As a developer, you do not know the Type. Imagine, you need to pass the anonymous type to a method, how would you do it ? Tricky, isn’t it.

If you do not have to individually process different properties of the Anonymous types, you can achieve this using Generic methods. For example, you can use following method to compare two anonymous types.

bool IsEqual<T>(T source, T itemToCompare)
{
return source.Equals(itemToCompare);
}
// Client Code
var point1 = new {X = 20, Y = 45};
var point2 = new {X = 20, Y = 45};

var comparisonResult = IsEqual(point1,point2);

But what if you need to process the individual properties of Anonymous types within the method ? For example, you want to increment the X and Y of Point by 1 (let’s ignore reflection for the moment)

One way to achieve this would be use Generic methods with Func parameters. For example,

T Execute<T>(T source, Func<T,T> incrementFunction)
{
return incrementFunction(source);
}

You can invoke the method as the following.

var result = Execute(point,(p)=> new {X=p.X + 1, Y=p.Y+1});

Let’s now explore another possibility. Consider a method that returns an anonymous type.

object GetPoint()
{
return new {X = 20, Y = 45};
}

How would one process the individual properties in the caller method ? Surely, following would fail to compile

// Following would fail to compile
var point = GetPoint();
var x= point.X;

Deconstruction won’t be a help either as anonymous types doesnt support it.

// Following would fail to compile
var (x,y) = GetPoint();

What we would require it to cast the returned object to anonymous type, that resembles the original. Let us write a quick extension method it.

public static class Extensions
{
public static T Cast<T>(this object source,T sampleType)
{
return (T)source;
}
}

Now you can use the return type by casting it to desired Anonymous Type and use it in your rest of code.

var point = GetPoint();
var result = point.Cast(new{X=default(int),Y=default(int)});
Console.WriteLine($"X={result.X},Y={result.Y}");

That’s it for now, Happy Coding.

Zoom Rectangle with OxyPlot

Let’s stick to OxyPlot for some more time. This time, we would attempt to change the color of Zoom Rectangle. For those who are new to Oxyplot, the control allows you to zoom in a particular location by permitting the user to draw rectangles in the graph. This particular rectangle is known as Zoom Rectangle.

You can enable the Zoom Rectangle by using the PlotController.

public PlotController ChartController { get; set; }

ChartController = new PlotController();
ChartController.BindMouseDown(OxyMouseButton.Left, PlotCommands.ZoomRectangle);

You can now bind the PlotController with your OxyPlot PlotView instance in XAML.

<oxy:PlotView Model="{Binding Model}" Controller="{Binding ChartController,UpdateSourceTrigger=PropertyChanged}"/>

While would enable the Zoom Rectangle, you would ideally would like to do a bit of Customization, for example, changing the appearance(color) of the rectangle.

You can do so by customizing the ZoomRectangleTemplate. Let’s change the default color of the Zoom Rectangle we just created.

<oxy:PlotView Model="{Binding Model}" Controller="{Binding ChartController,UpdateSourceTrigger=PropertyChanged}">
<oxy:PlotView.ZoomRectangleTemplate>
<ControlTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<Rectangle Fill="Orange" />
</Border>
</ControlTemplate>
</oxy:PlotView.ZoomRectangleTemplate>
</oxy:PlotView>

That’s all you need. You now have your fully customized Zoom Rectangle.

Oxyplot

Caliburn.Micro Template Pack now supports VS 2019

So glad to announce that Caliburn.Micro Template Pack now supports Visual Studio 2019.

Caliburn.Micro Template Pack for WPF contains a comprehensive collection of Project Templates and Code Snippets for developing WPF application using Caliburn.Micro. It also includes Bootstrap templates for SimpleContainer, MEF and Unity.

You can download the template from Visual Studio Marketplace

You can read more on the template here