Design Pattern For Beginners - Part 11: Implement Decouple Classes in Application

Welcome to the Design Pattern for Beginners article series. Thanks to all, special thanks to those who were with us from the beginning. If you are new to this series then I suggest you go through all the previous articles.

In this article we will learn how to implement the Implement Decouple Architecture in applications. Decoupling is very important in application development. It helps up to attach and detach components of any class without affecting another class.

The main goal of decoupling is to reduce dependency. Let's use an example to understand the concept. Think about a Desktop computer. If the monitor does not work then we just unplug it and replace it with a new one, even a different brand would work.

If the hard disk does not work then we just unplug it (hope you know how to unplug it! Ha ..Ha) and install a new one. Now, think of how to decouple each and every component? When we are changing one, it does not at all affect other components and the computer is running happily.

Now, our purpose is to implement the same kind of concept in software development. OK, one thing has been forgotten for explanation, tight coupling. Yes, it indicates that two entities are very much dependent on each other. If we change one then it will definitely effect another one.

OK, no more discussion. Let's implement the concept of decoupling.

How to implement?

Hmm…, one big question is, how to implement it? The solution is an interface. As the name suggests, it will be in the middle of two classes.

How it will come?

Let's see with an example. Here we will communicate with two classes using an interface.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. namespace InterfaceService  
  6. {  
  7.     public interface IService  
  8.     {  
  9.         void Serve();  
  10.     }  
  11.     public class Server : IService  
  12.     {  
  13.         public void Serve()  
  14.         {  
  15.             Console.WriteLine("Server executes");  
  16.         }  
  17.     }  
  18.     public class Consumer  
  19.     {  
  20.         IService obj;  
  21.         public Consumer(IService temp)  
  22.         {  
  23.             this.obj = temp;  
  24.         }  
  25.         public void Execute()  
  26.         {  
  27.             obj.Serve();  
  28.         }  
  29.     }  
  30. }
Let's discuss the code above. At first we have created an Interface called IService. Then we implemented the IService interface within the Server class. Now, let's discuss the Consumer class. Within the Consumer constructor we are assigning an object of the Iservice interface and this object is being set to a local objet of the IService interface.


Now you can see that nowhere in the Consumer class have we specified a class name server and hence we are achieving decoupling.

Let's call the consumer class from the client code.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. namespace DependencyInjection  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             Consumer C = new Consumer(new Server());  
  12.             C.Execute();  
  13.             Console.ReadLine();  
  14.         }  
  15.     }  
  16. }
Within the Main function we are creating an object of the Consumer class by passing an object of the server class. And we are calling the Execute function to execute the service.

Here is sample output.

Design-Pattern-1.jpg

Now the question is, how will it help us? What is the facility for that? Let's change the class name from Server to Server123.
  1. public class Server123 : IService  
  2. {  
  3.     public void Serve()  
  4.     {  
  5.         Console.WriteLine("Server executes");  
  6.     }  
  7. }  
  8. public class Consumer  
  9. {  
  10.     IService obj;  
  11.     public Consumer(IService temp)  
  12.     {  
  13.         this.obj = temp;  
  14.     }  
  15.     public void Execute()  
  16.     {  
  17.         obj.Serve();  
  18.     }   
  19. }
See, we have changed the server class name but does not change anything in the Consumer class. Now, just create an object of the new server class (Server123) from the client, as in the following.
  1. static void Main(string[] args)  
  2. {  
  3.     Consumer C = new Consumer(new Server123());  
  4.     C.Execute();  
  5.     Console.ReadLine();  
  6. }
And you will get the same output. Now again change the Class name from Consumer to Consumer123.


Have a look at the following code.

  1. public class Server : IService  
  2. {  
  3.     public void Serve()  
  4.     {  
  5.         Console.WriteLine("Server executes");  
  6.     }  
  7. }  
  8. public class Consumer123  
  9. {  
  10.     IService obj;  
  11.     public Consumer123(IService temp)  
  12.     {  
  13.         this.obj = temp;  
  14.     }  
  15.     public void Execute()  
  16.     {  
  17.         obj.Serve();  
  18.     }  
  19. }
Here is the client code:
  1. static void Main(string[] args)  
  2. {  
  3.     Consumer123 C = new Consumer123(new Server());  
  4.     C.Execute();  
  5.     Console.ReadLine();  
  6. }
Now, we have tuned up the Consumer class and within the Main() function (Client code) but it does not even touch the server class. And we will get the same output.
 
This is the advantage of decouple architecture.  Hope you understood the concept.