Patterns,Principles and Programming.

Have been thinking about putting together a collection of Jump Start Tutorials on some core concepts on Programming, finally getting everything together

Design Patterns

Design Principles

Code Smells and Refactoring Techniques

Design Patterns : Strategy Pattern

If there is one thing that is constant in every software development projects, then it has to be CHANGE. Requirements evolve overtime and you might end up with fairly different set of requirements that you initially started of. As developers one has to be aware of the possibility of change and design applications that are flexible to changes. You do not want your application to be fragile and rigid, that would be the least you would desire of your software design.

Let us consider the hypothetical situation where you were asked to develop a module that would sort a collection. The customers mentions he would like the module clients to be provided with ability to choose from the QuickSort and BubbleSort. To begin with, you thought you would depend on inheritance and create a SortBase class, which would be implemented include the abstract Sort method, and the implementation of common methods.

public class SortBase
{

    public IEnumerable<int> Read(string fileName)
    {

    }

    public abstract IEnumerable<int> Sort();

    public void Display()
    {

    }

}

public class QuickSort:SortBase
{

}

public class BubbleSort:SortBase
{

}

Just as you begin development, your Boss walks in and says – “Hey, you know what, I just heard from the stakerholders. They would like to add options to read the data from different format like JSON, CSV. And they would like to support more sorting algorithms as well.”.

If you were to use the earlier approach of inheritance, you would require a sub class for each combination of input type-sorting algorithm. This might get quite ugly soon and is difficult to maintain. Perhaps, inheritance wasn’t the right solution here, may be you should prefer composition over inheritance here.

At this point, you realize the input methods and sorting algorithms are prone to changes. Hence these needs to be isolated and encapsulated. If you could achieve so, then the parts which could vary, could change independently without affecting the crux of the application logic (which doesn’t change). At this point, you remember your friend talking about Strategy Pattern and thinks this might be a good use to apply it.

Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.

Let us look at the class diagram and see how does this different from the old solution.

As you can observe, with this design you could now add further behaviors in system without affecting the existing code. This is exactly what you would require for accommodating the changes you are expecting in the Input/Sorting algorithms.

Let us now go ahead and write our implementation using the Strategy pattern.

public interface IProduct<T>
{
    ISortAlgorithm<T> SortingAlgorithm { get; set; }
    IRead<T> Reader { get; set; }
    void Display(IEnumerable<T> data);
    IEnumerable<T> Read(string fileName);
    IEnumerable<T> Sort(IEnumerable<T> data);
}

public class Product<T> : IProduct<T>
{
    public ISortAlgorithm<T> SortingAlgorithm { get; set; }
    public IRead<T> Reader { get; set; }

    public IEnumerable<T> Sort(IEnumerable<T> data)
    {
        return SortingAlgorithm.Sort(data);
    }
    public IEnumerable<T> Read(string fileName)
    {
        return Reader.ReadData(fileName);
    }

    public void Display(IEnumerable<T> data)
    {
        Console.WriteLine("Displaying Data");
    }
}

The Product Class, now has two properties, SortingAlgorithm, and Reader of type ISortingAlgorithm<T> and IRead<T>. The Read and Sort methods makes use of these properties to do their operation. However, both methods DO NOT which concrete implementation of the ISortingAlgorithm<T> and IRead<T> are being used.

public interface IRead<T>
{
    IEnumerable<T> ReadData(string fileName);
}

public class CsvReader<T> : IRead<T>
{
    public IEnumerable<T> ReadData(string fileName)
    {
        Console.WriteLine($"Reading using {nameof(CsvReader<T>)}");
        return default;
    }
}

public class JsonReader<T> : IRead<T>
{
    public IEnumerable<T> ReadData(string fileName)
    {
        Console.WriteLine($"Reading using {nameof(JsonReader<T>)}");
        return default;
    }
}


public interface ISortAlgorithm<T>
{
    IEnumerable<T> Sort(IEnumerable<T> dataCollection);
}
public class BubbleSort<T> : ISortAlgorithm<T>
{
    public IEnumerable<T> Sort(IEnumerable<T> dataCollection)
    {
        Console.WriteLine($"Sorting {nameof(BubbleSort<T>)}");
        return default;
    }
}

public class QuickSort<T> : ISortAlgorithm<T>
{
    public IEnumerable<T> Sort(IEnumerable<T> dataCollection)
    {
        Console.WriteLine($"Sorting {nameof(QuickSort<T>)}");
        return default;
    }
}

At run time, the user could replace any sub classes of the contract for the properties, without the Product needing to be aware of the internals of their working.

static void Main(string[] args)
{
    var productInstance = new Product<int>();
    productInstance.SortingAlgorithm = new QuickSort<int>();
    productInstance.Reader = new JsonReader<int>();
    Console.WriteLine("Product Initialized and Algorithm assigned");

    Execute(productInstance,default);

    productInstance = new Product<int>();
    productInstance.SortingAlgorithm = new BubbleSort<int>();
    productInstance.Reader = new XmlReader<int>();
    Console.WriteLine("Product Initialized and Algorithm assigned");

    Execute(productInstance, default);

    productInstance = new Product<int>();
    productInstance.SortingAlgorithm = new BucketSort<int>();
    productInstance.Reader = new CsvReader<int>();
    Console.WriteLine("Product Initialized and Algorithm assigned");

    Execute(productInstance, default);

    Console.ReadLine();
}

public static void Execute(IProduct<int> product,string fileName)
{
    Console.WriteLine("Executing Client Code");
    var data = product.Read(fileName);
    var sortedData = product.Sort(data);
    product.Display(sortedData);
    Console.WriteLine("Completed Execution");
    Console.WriteLine();
}

Complete collection of articles on Design Patterns can be found here

Caliburn.Micro #005 : Bootstrapper with MEF

Previously, we learnt how to use SimpleContainer to set up our IoC Containers. We would be now looking into making the application more loosely coupled by leveraging the MEF. Just like with SimpleContainer, we would be focusing on the basic steps while configuring the IoC – Registering the IoC Container with Caliburn Micro and then registering the Service bindings. Let’s go ahead override the necessary methods

private CompositionContainer _Container;

protected override object GetInstance(Type service, string key)
{
  string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
  var exports = _Container.GetExportedValues(contract);
  if (exports.Any())
      return exports.First();
  else
      throw new Exception("Could not find the key");
}

protected override void BuildUp(object instance)
{
  _Container.SatisfyImportsOnce(instance);
}

protected override IEnumerable GetAllInstances(Type service)
{
  return _Container.GetExportedValues(AttributedModelServices.GetContractName(service));
}

We will now go ahead and register our Service Bindings. This is where things get interesting.

protected override void Configure()
{
  _Container = new CompositionContainer(
                new AggregateCatalog(AssemblySource.Instance.Select(x=> new AssemblyCatalog(x)).OfType())
                );
  var batch = new CompositionBatch();
  batch.AddExportedValue(new WindowManager());
  batch.AddExportedValue(new EventAggregator());
  batch.AddExportedValue(_Container);

  _Container.Compose(batch);
}

As seen in the code above, we are using the AssemblySource to parse the ViewModels in the Assembly.

That’s it in Bootstrapper, but do not forget to decorate your View Model class with [Export()] Attribute and Constructor with [ImportingConstructor]. (For injecting dependency)

[Export(typeof(IReport))]
public class ReportViewModel :Screen, IReport
{
  [ImportingConstructor]
  publicReportViewModel(IEventAggregator EventAggregator)
  {
    // Do Constructor tasks
  }
}

We will delve into EventAggregators later, but for the moment, consider it an example of how to inject a dependency in the constructor when working with MEF.

Code sample for this post can be found here. The complete list of tutorials on Caliburn.Micro can be accessed here