The following class breaks the open/closed principal:
public class Account
{
public decimal Interest { get; set; }
public decimal Balance { get; set; }
public decimal CalcInterest(string accType)
{
if (accType == "Regular")
{
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;
}
}
And it can be fixed like this:
public interface IAccount
{
decimal Balance { get; set; }
decimal CalcInterest();
}
public class RegularAccount : IAccount
{
public decimal Balance { get; set; }
public decimal CalcInterest()
{
var interest = (Balance * 4) / 100;
if (Balance < 1000)
interest -= (Balance * 2) / 100;
if (Balance < 50000)
interest += (Balance * 4) / 100;
return interest;
}
}
public class SalaryAccount : IAccount
{
public decimal Balance { get; set; }
public decimal CalcInterest()
{
return (Balance * 5) / 100;
}
}
public class CorporateAccount : IAccount
{
public decimal Balance { get; set; }
public decimal CalcInterest()
{
return (Balance * 3) / 100;
}
}
However the RegularAccount still breaks the principal due to the balance checks. How do you fix this?
Is the answer just to create more classes that implement the IAccount interface? e.g. Regular1000Account:IAccount, Regular5000Account:IAccount, Regular8000Account:IAccount, etc