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.

Why avoid Conversion Operators

No doubt that the Conversation Operators makes developers life easier by bring in a kind of substitutability, but it comes with a price. If not properly designed/used, it could result in subtle errors that can be easily ignored.
Consider the following code.
public class Car
{
  public string MakerName { get; set; }
  public Car(string Maker) => MakerName = Maker;
}
public class ElectricCar
{
  public string BrandName { get; set; }
  public ElectricCar(string Brand) => BrandName = Brand;
}
We have a class called Car, which exposes a single property – MakerName. We have another class ElectricCar, which exposes a property called BrandName. As seen, both classes are inherently incompatible, and you cannot implicitly/explicitly convert one to other. In order to solve this problem, we would be tempted to introduce an implicit conversion operator between the two classes.

We will modify ElectricCar as the following.

public class ElectricCar
{
  public string BrandName { get; set; }
  public ElectricCar(string Brand) => BrandName = Brand;
  public static implicit operator Car(ElectricCar car) => new  Car(car.BrandName);
}

We have added an implicit operator that supports conversion between ElectricCar and Car Classes. This works fine and you can now convert between the two classes. Let’s now create a method which updates the BrandName for the class Car.
public static void UpdateMarkerName(Car car, string MakerName) => car.MakerName =  MakerName;
By virtue of our implicit operator, we should be able to pass instances of both Car and Electric Car to this method. Let’s attempt to do so.
class Program
{
        
  static void Main(string[] args)
  {
     var _car = new Car("Toyota");
     var _electricCar = new ElectricCar("Toyota");

     UpdateMarkerName(_car, "Tesla");
     UpdateMarkerName(_electricCar, "Tesla");

     Console.WriteLine($"Car : {_car.MakerName}");
     Console.WriteLine($"Electric Car : {_electricCar.BrandName}");

     Console.ReadLine();
}
   public static void UpdateMarkerName(Car car, string MakerName) =>  car.MakerName = MakerName;
}
The output of above code would be curiously different, despite the implicit conversion.

Car : Tesla
Electric Car : Toyota

Of course, it is not hard to understand why. The instance of ElectricCar, thanks to the implicit operator implementation, would be converted to an instance of Car when passed to the UpdateMarkerName method. However, the scope of converted object is within the UpdateMarkerName class. The Method, updates the MakerName, but eventually throws away the instance. It has no reflection on the original instance. This is in stark contrast to when an instance of Car is being passed.

This kind of error can be easily overlooked by the developer and can lead to issues that are hard to trace. This is one of the reasons why we need to keep away from the Conversion Operators.

Design Patterns : Template Method

The purpose of a Template Method Pattern is to define the skelton of an algorithm, while deferring the exact steps to sub classes. There is plenty of literature on the internet detailing the pattern, so we will skip it and head right to the code.

As always, lets begin by defining the contract interface, in this case, an abstract method.

public abstract class BaseAlgorithm
{
        public void Execute()
        {
            Step1();
            Step2();
            Step3();
        }
        protected abstract void Step1();
        protected abstract void Step2();
        protected abstract void Step3();
}

Some of the implementation of Sub classes would be

public class AlgorithmA : BaseAlgorithm
{
        protected override void Step1() => Console.WriteLine($"{nameof(AlgorithmA)} - {nameof(Step1)}");
        protected override void Step2() => Console.WriteLine($"{nameof(AlgorithmA)} - {nameof(Step2)}");
        protected override void Step3() => Console.WriteLine($"{nameof(AlgorithmA)} - {nameof(Step3)}");
}

public class AlgorithmB : BaseAlgorithm
{
        protected override void Step1() => Console.WriteLine($"{nameof(AlgorithmB)} - {nameof(Step1)}");
        protected override void Step2() => Console.WriteLine($"{nameof(AlgorithmB)} - {nameof(Step2)}");
        protected override void Step3() => Console.WriteLine($"{nameof(AlgorithmB)} - {nameof(Step3)}");
}

public class AlgorithmC : BaseAlgorithm
{
        protected override void Step1() => Console.WriteLine($"{nameof(AlgorithmC)} - {nameof(Step1)}");
        protected override void Step2() => Console.WriteLine($"{nameof(AlgorithmC)} - {nameof(Step2)}");
        protected override void Step3() => Console.WriteLine($"{nameof(AlgorithmC)} - {nameof(Step3)}");
}

 

The Client, on other hand, doesn’t quite need to need know the details of what happens inside the classes.

BaseAlgorithm algo1 = new AlgorithmA();
algo1.Execute();

BaseAlgorithm algo2 = new AlgorithmB();
algo2.Execute();

BaseAlgorithm algo3 = new AlgorithmC();
algo3.Execute();

Code samples can be found here. Complete list of Patterns and Principles could be found here.

Design Patterns : Chain of Responsibility

The intend of Chain of Responibility Pattern is to avoid coupling the sender of a request to its reciever by giving more than one object change to handle the request.

Let’s try to mimic the execution of classical Waterfall Model with CoR. Let’s begin by declaring the contract interface.

public interface IWaterfall
    {
        void Execute();
        IWaterfall NextStage { get; set; }
    }

And our sub classes.

internal class Requirements : IWaterfall
{
        public IWaterfall NextStage {get;set;}

        public void Execute()
        {
            Console.WriteLine(nameof(Requirements));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

internal class Design : IWaterfall
{
        public IWaterfall NextStage { get; set; }

        public void Execute()
        {
            Console.WriteLine(nameof(Design));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

internal class Implementation : IWaterfall
{
        public IWaterfall NextStage { get; set; }

        public void Execute()
        {
            Console.WriteLine(nameof(Implementation));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

internal class Verification : IWaterfall
{
        public IWaterfall NextStage { get; set; }

        public void Execute()
        {
            Console.WriteLine(nameof(Verification));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

internal class Deployment : IWaterfall
{
        public IWaterfall NextStage { get; set; }

        public void Execute()
        {
            Console.WriteLine(nameof(Deployment));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

internal class Maintenance : IWaterfall
{
        public IWaterfall NextStage { get; set; }

        public void Execute()
        {
            Console.WriteLine(nameof(Maintenance));

            if (NextStage is IWaterfall)
                NextStage.Execute();
        }
}

The final step is link up the chain and get the execution rolling from client.

IWaterfall Handler1 = new Requirements();
IWaterfall Handler2 = new Design();
IWaterfall Handler3 = new Implementation();
IWaterfall Handler4 = new Verification();
IWaterfall Handler5 = new Deployment();
IWaterfall Handler6 = new Maintenance();

Handler1.NextStage = Handler2;
Handler2.NextStage = Handler3;
Handler3.NextStage = Handler4;
Handler4.NextStage = Handler5;
Handler5.NextStage = Handler6;

Handler1.Execute();

As you can see the responsibility is handled by the chain of classes, each executing a single responsibility (following Single Responsibility Principle). Also, the functionality can be extended by further linking up the chain, thereby satisfying the Open-Closed Principle.

Code samples can be found here. Complete list of Patterns and Principles could be found here.

Design Patterns : Fascade Pattern

Fascade, name being an analogy to an architectural fascade, intends set the tone for the entire functionality by providing a simplified yet effective interface wrapping away the complex, pooly designed collection of APIs.

Wrong Code

Consider following set of Classes.

public class User : IUser
{
        int _uInstance;
        private bool _IsRunning = false;

        public User(int UserID) => _uInstance = UserID;
        public void StartRunning()
        {
            Console.WriteLine($"User {_uInstance} Running");
            _IsRunning = true;
        }
        public void StopRunning(int UserID) => _IsRunning = false;
        
}

public class GPSTracking : IGPSTracking
{
        public void Start() => Console.WriteLine($"GPS started");
        public void Stop() { }
        public void InitiatizeGPSTracker() { }
        public void TroubleShoot() { }
}

public class MusicPlayer : IMusicPlayer
{
        public void Start(string AlbumName,string Song) => Console.WriteLine($"Music Player - Song {Song} , Album {AlbumName}");
        public void Stop() { }
        public void SearchAlbum(string Song) { }
        public bool Loop { get; set; }
        public void Next() { }
        public void Previous() { }
}

 

The Client Code could be

IUser userInstance = new User(1);
userInstance.StartRunning();

IGPSTracking gpsInstance = new GPSTracking();
gpsInstance.Start();

IMusicPlayer mplayerInstance = new MusicPlayer();
mplayerInstance.Start("MyAlbum","MySong");

As you can see, the Client class is invoking 3 APIs separately and the code look a mess.

Fascade In Action

Idea behind Fascade is to provide a simplified interface. Let’s introduce a Fascade Class now.

class FascadeClass
{
        IUser _uInstance;
        IGPSTracking _gInstance;
        IMusicPlayer _mInstance;

        string _Song;
        string _album;

        
        public FascadeClass(IUser uInstance,IGPSTracking gInstance, IMusicPlayer mInstance)
        {
            _uInstance = uInstance;
            _gInstance = gInstance;
            _mInstance = mInstance;

        }

        public void SetSong(string Album, string Song) { _Song = Song; _album = Album; }

        public void StartRunning()
        {
            _uInstance.StartRunning();
            _gInstance.Start();
            _mInstance.Start(_album, _Song);
        }

        public void StopRunning() { }
}

 

The Client Code would be now much cleaner as we have wrapped the complexity of IUser, IGPSTracking and IMusicPlayer within the Fascade Class.

 FascadeClass fInstance = new FascadeClass(new User(1), new GPSTracking(), new MusicPlayer());
fInstance.SetSong("MyAlbum", "MySong");
fInstance.StartRunning();

Code samples can be found here. Complete list of Patterns and Principles could be found here.

 

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 Princples

Code Smells and Refactoring Techniques

 

Design Patterns : Strategy Pattern

Strategy Pattern lets you create a family of strategies (algorithm) encapsulated into separate interchangeable classes. In our example, we will consider a Client class which needs to invoke different sorting algorithm.

 

Let’s first create the contract interface for different Sorting algorithm.

public interface ISortStrategy
{
   void Sort(int[] ArrayToSort);
}

Now that we have our interface ready, let’s go ahead and implement different sorting algorithms based on it.[/code]

public class QuickSort : ISortStrategy
{
  public void Sort(int[] ArrayToSort)
  {
    Console.WriteLine("Executing Quick Sort");
  }
}

public class BubbleSort : ISortStrategy
{
  public void Sort(int[] ArrayToSort)
  {
    Console.WriteLine("Executing Bubble Sort");
  }
}

public class MergeSort : ISortStrategy
{
  public void Sort(int[] ArrayToSort)
  {
    Console.WriteLine("Executing Merge Sort");
  }
}

public class HeapSort : ISortStrategy
{
  public void Sort(int[] ArrayToSort)
  {
   Console.WriteLine("Executing Heap Sort");
  }
}

Now let’s head to our Client Class and Inject the Strategy, which would be used to sort the Array.

internal class Client
{

  private int[] _IntArray;

  public Client(int[] IntArray)
  {
    _IntArray = IntArray;
  }

  public void Sort(ISortStrategy Strategy)
  {
   Strategy.Sort(_IntArray);
  }
}

As you can see , the Client Class is devoid of any direct dependencies as well as any nasty conditional statements. Yes, its a good idea to do away with Conditional Statements , especially those long if-else or switch cases as it can increase the cyclomatic complexity of the code. The Strategy is injected directly in the client, which invokes it.

Complete collection of articles on Design Patterns can be found here