Understanding SOLID Violations in a Class (With Example and Solution)
What issues do you see in the below code? Which SOLID principles are being violated, and how would you correct them? public class Account { public decimal balance { get; set; } public decimal CalculateInterest(string accountType) { decimal interest = 0; if (accountType.Equals("Regular")) { interest = balance * 0.4m; if (balance < 1000) interest -= balance * 0.2m; else if (balance < 50000) interest += balance * 0.4m; } else if (accountType.Equals("Salary")) { interest = balance * 0.5m; } return interest; } } Problems in the Code • SRP Violated: Single Responsibility Principle • OCP Violated: Open/Closed Principle (Other SOLID principles are not applicable yet.) Why is SRP Violated? • Account class handles: Balance data Interest calculation logic • Two reasons to change = SRP violation. SRP says: A class should have only one reason to change. Why is OCP Violated? • Adding new account types (e.g., "Premium") needs modifying CalculateInterest. • Risk of introducing bugs while changing old code. OCP says: • Open for extension • Closed for modification Correct Approach: Using Polymorphism (Inheritance) • Create an abstract base class Account. • Subclasses like RegularAccount, SalaryAccount override CalculateInterest. • Follows SRP and OCP. Example: public abstract class Account { public decimal Balance { get; set; } public abstract decimal CalculateInterest(); } public class RegularAccount : Account { public override decimal CalculateInterest() { decimal interest = Balance * 0.4m; if (Balance < 1000) interest -= Balance * 0.2m; else if (Balance < 50000) interest += Balance * 0.4m; return interest; } } public class SalaryAccount : Account { public override decimal CalculateInterest() { return Balance * 0.5m; } } using Strategy Pattern we can correct this code • Create an IInterestCalculator interface. • Create separate classes for each account type. • Account class delegates calculation to the correct strategy. public interface IInterestCalculator { decimal CalculateInterest(decimal balance); } public class RegularAccountInterestCalculator : IInterestCalculator { public decimal CalculateInterest(decimal balance) { decimal interest = balance * 0.4m; if (balance < 1000) interest -= balance * 0.2m; else if (balance < 50000) interest += balance * 0.4m; return interest; } } public class SalaryAccountInterestCalculator : IInterestCalculator { public decimal CalculateInterest(decimal balance) { return balance * 0.5m; } } Modified Account Class public class Account { public decimal Balance { get; set; } private readonly IInterestCalculator _interestCalculator; public Account(IInterestCalculator interestCalculator) { _interestCalculator = interestCalculator; } public decimal CalculateInterest() { return _interestCalculator.CalculateInterest(Balance); } } Final Benefits • SRP Achieved: Account only manages balance. Separate classes manage interest logic. • OCP Achieved: New account types? Just add a new class! • Code is maintainable, testable, and professional.

What issues do you see in the below code? Which SOLID principles are being violated, and how would you correct them?
public class Account
{
public decimal balance { get; set; }
public decimal CalculateInterest(string accountType)
{
decimal interest = 0;
if (accountType.Equals("Regular"))
{
interest = balance * 0.4m;
if (balance < 1000)
interest -= balance * 0.2m;
else if (balance < 50000)
interest += balance * 0.4m;
}
else if (accountType.Equals("Salary"))
{
interest = balance * 0.5m;
}
return interest;
}
}
Problems in the Code
• SRP Violated: Single Responsibility Principle
• OCP Violated: Open/Closed Principle
(Other SOLID principles are not applicable yet.)
Why is SRP Violated?
• Account class handles:
Balance data
Interest calculation logic
• Two reasons to change = SRP violation.
SRP says: A class should have only one reason to change.
Why is OCP Violated?
• Adding new account types (e.g., "Premium") needs modifying CalculateInterest.
• Risk of introducing bugs while changing old code.
OCP says:
• Open for extension
• Closed for modification
Correct Approach:
Using Polymorphism (Inheritance)
• Create an abstract base class Account.
• Subclasses like RegularAccount, SalaryAccount override CalculateInterest.
• Follows SRP and OCP.
Example:
public abstract class Account
{
public decimal Balance { get; set; }
public abstract decimal CalculateInterest();
}
public class RegularAccount : Account
{
public override decimal CalculateInterest()
{
decimal interest = Balance * 0.4m;
if (Balance < 1000)
interest -= Balance * 0.2m;
else if (Balance < 50000)
interest += Balance * 0.4m;
return interest;
}
}
public class SalaryAccount : Account
{
public override decimal CalculateInterest()
{
return Balance * 0.5m;
}
}
using Strategy Pattern we can correct this code
• Create an IInterestCalculator interface.
• Create separate classes for each account type.
• Account class delegates calculation to the correct strategy.
public interface IInterestCalculator
{
decimal CalculateInterest(decimal balance);
}
public class RegularAccountInterestCalculator : IInterestCalculator
{
public decimal CalculateInterest(decimal balance)
{
decimal interest = balance * 0.4m;
if (balance < 1000)
interest -= balance * 0.2m;
else if (balance < 50000)
interest += balance * 0.4m;
return interest;
}
}
public class SalaryAccountInterestCalculator : IInterestCalculator
{
public decimal CalculateInterest(decimal balance)
{
return balance * 0.5m;
}
}
Modified Account Class
public class Account
{
public decimal Balance { get; set; }
private readonly IInterestCalculator _interestCalculator;
public Account(IInterestCalculator interestCalculator)
{
_interestCalculator = interestCalculator;
}
public decimal CalculateInterest()
{
return _interestCalculator.CalculateInterest(Balance);
}
}
Final Benefits
• SRP Achieved:
Account only manages balance.
Separate classes manage interest logic.
• OCP Achieved:
New account types? Just add a new class!
• Code is maintainable, testable, and professional.