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.