S —Single responsibility principle
In programming, the Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software.
You may have heard the quote: “Do one thing and do it well”.
This refers to the single responsibility principle.
Let’s do an example of how to write a piece of code that violates this principle.
class Account | ||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
void CreateAccount(Database db, obj accDetails) | ||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
try | ||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
db.Add(accDetails); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
catch (Exception ex) | ||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||
db.LogError("An error occured: ", ex.ToString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
File.WriteAllText("\LocalErrors.txt", ex.ToString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
}
We notice how the Let’s try to correct it.
Now we have two classes that each has one responsibility; to create a post and to log an error, respectively. O — Open/closed principleIn programming, the open/closed principle states that software entities (classes, modules, functions, etc.) should be open for extensions, but closed for modification. Let’s take an example of bank accounts like regular savings, salary saving, corporate etc. for different customers. As for each customer type, there are different rules and different interest rates. The code below violates OCP principle if the bank introduces a new Account type. Said code modifies this method for adding a new account type. public class Account { public decimal Interest { get; set; } public decimal Balance { get; set; } // members and function declaration public decimal CalcInterest(string accType) { if (accType == "Regular") // savings { Interest = (Balance * 4) / 100; if (Balance < 1000) Interest -= (Balance * 2) / 100; if (Balance < 50000) Interest += (Balance * 4) / 100; } else if (accType == "Salary") // salary savings { Interest = (Balance * 5) / 100; } else if (accType == "Corporate") // Corporate { Interest = (Balance * 3) / 100; } return Interest; } } We can apply OCP by using interface, abstract class, abstract methods and virtual methods when you want to extend functionality. Here I have used interface for example only but you can go as per your requirement. interface IAccount { // members and function declaration, properties decimal Balance { get; set; } decimal CalcInterest(); } //regular savings account public class RegularSavingAccount : IAccount { public decimal Balance { get; set; } = 0; public decimal CalcInterest() { decimal Interest = (Balance * 4) / 100; if (Balance < 1000) Interest -= (Balance * 2) / 100; if (Balance < 50000) Interest += (Balance * 4) / 100; return Interest; } } //Salary savings account public class SalarySavingAccount : IAccount { public decimal Balance { get; set; } = 0; public decimal CalcInterest() { decimal Interest = (Balance * 5) / 100; return Interest; } } //Corporate Account public class CorporateAccount : IAccount { public decimal Balance { get; set; } = 0; public decimal CalcInterest() { decimal Interest = (Balance * 3) / 100; return Interest; } } In the above code three new classes are created; regular saving account, SalarySavingAccount, and CorporateAccount, by extending them from IAccount. This solves the problem of modification of class and by extending interface, we can extend functionality. Above code is implementing both OCP and SRP principle, as each class has single is doing a single task and we are not modifying class and only doing an extension. Liskov Substitution Principle (LSP)Definition by Robert C. Martin: Functions that use pointers or references to base classes must be able to use objects of derived classes without knowin |