درک تخلفات جامد در یک کلاس (با مثال و راه حل)

در کد زیر چه مواردی را مشاهده می کنید؟ کدام اصول محکم نقض می شود و چگونه آنها را اصلاح می کنید؟
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;
}
}
مشکلات موجود در کد
• SRP نقض شده: اصل مسئولیت واحد
• OCP نقض شده: اصل باز/بسته
(سایر اصول جامد هنوز کاربردی نیست.)
چرا SRP نقض می شود؟
• دستگیره کلاس حساب:
داده های تعادل
منطق محاسبه بهره
• دو دلیل برای تغییر = نقض SRP.
SRP می گوید: یک کلاس فقط باید یک دلیل برای تغییر داشته باشد.
چرا OCP نقض می شود؟
• افزودن انواع حساب جدید (به عنوان مثال ، “حق بیمه”) نیاز به تغییر محاسبه کننده دارد.
• خطر معرفی اشکالات هنگام تغییر کد قدیمی.
OCP می گوید:
• برای پسوند باز کنید
• برای اصلاح بسته شده است
رویکرد صحیح:
با استفاده از پلی مورفیسم (وراثت)
• یک حساب کلاس پایه انتزاعی ایجاد کنید.
• زیر کلاسهای مانند Accarcount ، SalaryAccount Override محاسبه کننده است.
• SRP و OCP را دنبال می کند.
مثال:
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;
}
}
با استفاده از الگوی استراتژی می توانیم این کد را اصلاح کنیم
• یک رابط IinterestCalculator ایجاد کنید.
• برای هر نوع حساب کلاس های جداگانه ایجاد کنید.
• نمایندگان کلاس حساب محاسبه به استراتژی صحیح.
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;
}
}
کلاس حساب اصلاح شده
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);
}
}
مزایای نهایی
• SRP به دست آورد:
حساب فقط تعادل را مدیریت می کند.
کلاسهای جداگانه منطق علاقه را مدیریت می کنند.
• OCP به دست آورد:
انواع حساب جدید؟ فقط یک کلاس جدید اضافه کنید!
• کد قابل حفظ ، قابل آزمایش و حرفه ای است.