Skip to main content

Importance of Solid Principles in Real time Scenario by #RathrolaPremKumar


Most of the modern programming languages including C# support objected oriented programming. Features such as encapsulation, inheritance, overloading and polymorphism are code level features. Using these features is just one part of the story.
Equally important is to apply some object oriented design principles while writing your C# code. SOLID principles is a set of five such principles--namely Single Responsibility Principle, Open/Closed Principle, Liskov Substitution Principle, Interface Segregation Principle and Dependency Inversion Principle. Applying these time proven principles make your code structured, neat and easy to maintain. 
In this article we shall discusses SOLID principles and also illustrates how they can be applied to your C# code

What is Solid?
SOLID is an acronym for five principles of architecture.
S – Single Responsibility Principle
O – Open Close Principle
L – Liskov Substitution Principle
I –Interface Segregation Principle
D – Dependency Inversion Principle
Single Responsibility Principle (SRP)
It says that every class should have single responsibility. A class should not have more than one reason to change.
Example 
Suppose, you have created a class XmlValidator for XML validation, which has the responsibility to validate XML.
If there is a need to update XML, then a separate class should be created for the same. XmlValidator class should not be used for updating XML
  1. public class XmlValidator   
  2.     {  
  3.   
  4.         public void Validate()  
  5.         {  
  6.   
  7.               
  8.         }  
  9.          
  10.     }   
For updating a new class, it should be created. 
  1. public class XmlUpdate  
  2.     {  
  3.   
  4.         public void DoUpdate()  
  5.         {  
  6.   
  7.   
  8.         }  
  9.   
  10.   
  11.     }   
Open Close Principle (OCP)
A class should be open for an extension and closed for the modification.
Example 
Suppose, we have a class name Customer, which has a property InvoiceNumber, which has an integer type 
  1. public class Customer  
  2.     {  
  3.         public int InvoiceNumber  
  4.         {  
  5.             get;  
  6.             set;  
  7.   
  8.         }  
  9.     }   
In the future, if the requirement changes now, InvoiceNumber should be alphanumeric rather than only an integer. Hence, in this case, you should create a subclass CustomerNew with a same property but different datatype rather than modifying the previous one. 
  1. public class CustomerNew : Customer  
  2.     {  
  3.   
  4.         public new String InvoiceNumber  
  5.         {  
  6.             get;  
  7.             set;  
  8.   
  9.         }  
  10.     }   
Liskov Substitution Principle (LSP)
A parent object should be able to replace its child during runtime polymorphism.
Example 
Suppose, you have two classes, Cooler and Fan, both are inherited from a common interface named ISwitch, which has three methods- On, Off and Regulate. 
  1. public interface ISwitch  
  2.     {  
  3.         void On();  
  4.         void Off();  
  5.     }  
  6.   
  7.     public class Cooler : ISwitch  
  8.     {  
  9.         public void On()  
  10.         {  
  11.               
  12.         }  
  13.         public void Off()  
  14.         {  
  15.   
  16.         }  
  17.   
  18.         public void Regulate()  
  19.         {  
  20.   
  21.         }  
  22.   
  23.     }  
  24.   
  25.     public class Fan : ISwitch  
  26.     {  
  27.         public void On()  
  28.         {  
  29.   
  30.         }  
  31.   
  32.         public void Off()  
  33.         {  
  34.   
  35.         }  
  36.         public void Regulate()  
  37.         {  
  38.   
  39.         }  
  40.   
  41.     }  
  42.   
  43.     public class MainClass  
  44.     {  
  45.         public void AddObject()  
  46.         {  
  47.             List<ISwitch> Switch = new List<ISwitch>();  
  48.             Switch.Add(new Cooler());  
  49.             Switch.Add(new Fan());  
  50.             
  51.             foreach (var o in Switch)  
  52.             {  
  53.                 o.Regulate();  
  54.             }  
  55.         }  
  56.     }   
Everything was fine until a new class introduced for same interface named Bulb, which has only two methods On and Off. It does not have Regulate method. Thus Bulb class is given below. 
  1. public class Bulb : ISwitch  
  2.     {  
  3.         public void On()  
  4.         {  
  5.   
  6.         }  
  7.   
  8.         public void Off()  
  9.         {  
  10.   
  11.         }  
  12.         public void Regulate()  
  13.         {  
  14.             throw new NotImplementedException();  
  15.         }  
  16.   
  17.     }   
Now, AddObject method will be updated, as shown below. 
  1. public void AddObject()  
  2.         {  
  3.             List<ISwitch> Switch = new List<ISwitch>();  
  4.             Switch.Add(new Cooler());  
  5.             Switch.Add(new Fan());  
  6.             Switch.Add(new Bulb());            
  7.   
  8.             foreach (var o in Switch)  
  9.             {  
  10.                 o.Regulate();  
  11.             }  
  12.         }   
In this case, Regulate method will throw an error.
One horrible solution to this problem is to put an if condition. 
  1. foreach (var o in Switch)  
  2.             {  
  3.   
  4. if(o is Bulb)  
  5.     continue;  
  6.   
  7.                 o.Regulate();  
  8.             }   
This is an example of bad design, if above condition is used somewhere, it clearly means that there is a violation of LSK principle.
Interface Segregation Principle (ISP)
Client specific interfaces are better than general purpose interfaces.
Suppose, we have one interface for clicking.
  1. public interface IClick{   
  2.     void onClick(Object obj);  
  3. }  
As time passes, new requirement comes for adding one more function onLongClick. You need to add this method in already created interface.
  1. public interface IClick{   
  2.     void onClick(Object obj);  
  3.     void onLongClick(Object obj);  
  4. }  
After some time, one new requirement comes for adding function for touch also and you need to add the method in the same interface
  1. public interface IClick{   
  2.     void onClick(Object obj);  
  3.     void onLongClick(Object obj);  
  4.     void onTouch(Object obj);  
  5. }  
At this point, you need to decide to change the name of interface too because touch is different than click.
In this way, this interface becomes a problem—generic and polluted. At this stage, ISP comes into play.
Why Generic Interface creates problem?
Suppose, some clients need only onClick function and some need only onTouch function, then one will be useless for both. Hence ISP gives the solution, which splits the interface into two interfaces.
ITouch and IClick. The client which has required onClick can implement IClick, which needs onTouch. It can implement ITouch and when it needs both, it can implement both.
  1. public interface IClick{   
  2.     void onClick(Object obj);  
  3.     void onLongClick(Object obj);  
  4. }  
  5.   
  6. public interface ITouch{   
  7.     void onClick(Object obj);  
  8.     void onTouch(Object obj);  
  9. }  
Dependency Inversion Principle (ISP)
It states two points, where the first point is a higher level module, which should not depend on a low level module. Both should depend on abstraction. The second point is abstraction, which should not depend on detail.
Detail should depend on abstraction.
In other words, no object should be created inside a class. They should be passed or injected from outside. When it  is received, it will be an interface rather than a class.
Here is a bad design without using Dependency Injection. 
  1. class Student  
  2. {  
  3.     // Handle to EventLog writer to write to the logs  
  4.     LogWriter writer = null;  
  5.     // This function will be called when the student has problem  
  6.     public void Notify(string message)  
  7.     {  
  8.         if (writer == null)  
  9.         {  
  10.             writer = new LogWriter();  
  11.         }  
  12.         writer.Write(message);  
  13.     }  
  14. }   
This is also a bad design. 
  1. class Student  
  2. {  
  3.     // Handle to EventLog writer to write to the logs  
  4.     LogWriter writer = null;  
  5. Public Student(LogWriter writer)  
  6.     {  
  7.   
  8.      This.writer = writer;  
  9. }  
  10.     // This function will be called when the student has problem  
  11.     public void Notify(string message)  
  12.     {  
  13.         writer.Write(message);  
  14.     }  
  15. }   
The written classes given above are bad designs because in the case of a change in LogWrite, you have to disturb Student class. We should use an interface inside Student instead of a class.
With Dependency Injection, the code is given, as shown below. 
  1. class Student  
  2. {  
  3.     // Handle to EventLog writer to write to the logs  
  4.     ILogWriter writer = null;  
  5. Public Student(ILogWriter writer)  
  6.     {  
  7.   
  8.       This.writer = writer;  
  9. }  
  10.     // This function will be called when the student has problem  
  11.     public void Notify(string message)  
  12.     {  
  13.         writer.Write(message);  
  14.     }  

Comments

Popular posts from this blog

ERROR: Cannot resolve the collation conflict between SQL_Latin1_General_CP1_CI_AS and Latin1_General_CI_AS_KS_WS in the equal to operation

ERROR: Cannot resolve the collation conflict between SQL_Latin1_General_CP1_CI_AS and Latin1_General_CI_AS_KS_WS in the equal to operation
dont get panic if u get the following error while in your joinings, there is a simple way to solve this.
it is because of collation settings on two columns we are doing joinings. it is because of collation settings on two columns we are doing joinings
First step is to figure out what are two colaltion that cause for conflicts. Let us assume that collation has not been set at the column level and instead at db level, then we have to execute two simple statements as below.

Statements: Select DATABASEPROPERTYYEX('DB1',N'Collation') Select DATABASEPROPERTYYEX('DB2',N'Collation')
One more thing, make a note that if you are on sharepoint you will get error as below
Latin_General_CI_AS_KS_WS. if you are on most any other database and use the dafault settings you may get this SQL_Latin_General_CP1_CI_AS.
Now we have to do some…

How To Create The Data Adapter Object Using ADO.NET by #RathrolaPremKumar

By reading this article, you will learn key points in ADO.NET, as given below. What is Data Adapter?Primary Data Adapters for the databases.Data Adapter properties.Methods used by Data Adapter.How to create Data Adapter with an example? Let’s start our demo with a Data Adapter introduction. Actually, we use Data Adapter object to establish the connection to the data source and manage the movement of date to and from the database. What is Data Adapter? A data adapter aobject serves as a bridge between a data set object and Data Source such as a database to retrieve and save the data. Data adapter contains a set of database commands and a database connection, which we use to fill a dataset object and update the Data Source. Primary data adapters for databases? .NET makes two primary data adapters available for use with the databases. Other data adapters can also be integrated with Visual Studio .NET. Primary Data Adapters are mentioned below. OleDbData Adapter, which is suitable for use wi…

Work 9 to 6 for Salary and 6 to 9 for Career

How much time one must spend in office, the subject line of the Post is something I have heard from a client several years back and believe the best of all choices. She was in executive rank and was highly successful in both office & home fronts.................................................................... She said following “Souvik, you get a salary to do 40 hours of work per week. You must come on time at 9 am and work efficiently to plan & finish it by 6 pm. Whatever you are doing during this time, you must try to do it in the best possible way. You should plan so that you do not sign up for more work than what you can deliver. Also manage your priorities & timing to avoid work fluctuations as much as practically possible.”  I nodded head as what she said is something everybody knows. She continued. “However, 9-6 work will only help you “earn” your salary. It will not be good enough to offer a sustained growth, especially in later part of your career. If you really w…