Last active
October 4, 2023 10:03
-
-
Save kumar-rajeswaran/5f3955d4ce6a4ed479eacf27982cb3ef to your computer and use it in GitHub Desktop.
SOLID in Software engineering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SOLID is an acronym representing five principles | |
| that are intended to guide software design and make software | |
| more understandable, flexible, and maintainable. | |
| These principles are widely used in object-oriented programming, | |
| and they form the foundation of good software design practices. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Single Responsibility Principle (SRP) | |
| Problem: | |
| A class that handles user authentication is also responsible for sending emails. | |
| class AuthManager | |
| { | |
| public void AuthenticateUser(User user) | |
| { | |
| // Authentication logic | |
| } | |
| public void SendEmail(User user, string message) | |
| { | |
| // Email sending logic | |
| } | |
| } | |
| Solution: | |
| Separate the responsibilities into different classes. | |
| class AuthManager | |
| { | |
| public void AuthenticateUser(User user) | |
| { | |
| // Authentication logic | |
| } | |
| } | |
| class EmailSender | |
| { | |
| public void SendEmail(User user, string message) | |
| { | |
| // Email sending logic | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Open/Closed Principle (OCP) | |
| Problem: | |
| An application has a class for calculating bonuses, but the logic needs to change for different types of employees. | |
| class BonusCalculator | |
| { | |
| public double CalculateBonus(Employee employee) | |
| { | |
| // Bonus calculation logic | |
| } | |
| } | |
| Solution: | |
| Create an interface for bonus calculation and implement it for different employee types. | |
| interface IBonusCalculator | |
| { | |
| double CalculateBonus(Employee employee); | |
| } | |
| class StandardBonusCalculator : IBonusCalculator | |
| { | |
| public double CalculateBonus(Employee employee) | |
| { | |
| // Standard bonus calculation logic | |
| } | |
| } | |
| class SpecialBonusCalculator : IBonusCalculator | |
| { | |
| public double CalculateBonus(Employee employee) | |
| { | |
| // Special bonus calculation logic | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Liskov Substitution Principle (LSP) | |
| Problem: | |
| Derived classes don't adhere to the behavior expected from the base class. | |
| class Rectangle | |
| { | |
| public virtual void SetWidth(int width) | |
| { | |
| // Set width | |
| } | |
| public virtual void SetHeight(int height) | |
| { | |
| // Set height | |
| } | |
| } | |
| class Square : Rectangle | |
| { | |
| public override void SetWidth(int width) | |
| { | |
| base.SetWidth(width); | |
| base.SetHeight(width); | |
| } | |
| public override void SetHeight(int height) | |
| { | |
| base.SetHeight(height); | |
| base.SetWidth(height); | |
| } | |
| } | |
| Solution: | |
| Refactor the design to adhere to the LSP. | |
| class Shape | |
| { | |
| public virtual void SetDimensions(int width, int height) | |
| { | |
| // Set width and height | |
| } | |
| } | |
| class Rectangle : Shape | |
| { | |
| public override void SetDimensions(int width, int height) | |
| { | |
| base.SetDimensions(width, height); | |
| // Set specific dimensions for a rectangle | |
| } | |
| } | |
| class Square : Shape | |
| { | |
| public override void SetDimensions(int width, int height) | |
| { | |
| if (width != height) | |
| { | |
| throw new InvalidOperationException("Width and height must be equal for a square."); | |
| } | |
| base.SetDimensions(width, height); | |
| // Set specific dimensions for a square | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Interface Segregation Principle (ISP) | |
| Problem: | |
| A class is forced to implement methods it doesn't need. | |
| interface IWorker | |
| { | |
| void Work(); | |
| void Eat(); | |
| } | |
| class Robot : IWorker | |
| { | |
| public void Work() | |
| { | |
| // Robot work logic | |
| } | |
| public void Eat() | |
| { | |
| // Robot can't eat, but forced to implement the method | |
| } | |
| } | |
| Solution: | |
| Split the interface into smaller, more specific interfaces. | |
| interface IWorker | |
| { | |
| void Work(); | |
| } | |
| interface IEater | |
| { | |
| void Eat(); | |
| } | |
| class Robot : IWorker | |
| { | |
| public void Work() | |
| { | |
| // Robot work logic | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Dependency Inversion Principle (DIP) | |
| Problem: | |
| High-level modules depend on low-level modules, causing high-level modules to be less flexible. | |
| class DatabaseConnection | |
| { | |
| // Database connection logic | |
| } | |
| class UserManager | |
| { | |
| private DatabaseConnection _databaseConnection; | |
| public UserManager() | |
| { | |
| _databaseConnection = new DatabaseConnection(); | |
| } | |
| // UserManager logic using _databaseConnection | |
| } | |
| Solution: | |
| Depend on abstractions (interfaces) rather than concrete implementations. | |
| interface IDatabaseConnection | |
| { | |
| // Database connection methods | |
| } | |
| class DatabaseConnection : IDatabaseConnection | |
| { | |
| // Database connection logic | |
| } | |
| class UserManager | |
| { | |
| private IDatabaseConnection _databaseConnection; | |
| public UserManager(IDatabaseConnection databaseConnection) | |
| { | |
| _databaseConnection = databaseConnection; | |
| } | |
| // UserManager logic using _databaseConnection | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment