我已经阅读了很多关于此的文章,但我仍然有 2 个问题。
问题 #1 - 关于依赖倒置:
它指出高级类不应该依赖于低级类。两者都应该依赖于抽象。抽象不应该依赖于细节。细节应该取决于抽象。
例如 :
public class BirthdayCalculator
{
private readonly List<Birthday> _birthdays;
public BirthdayCalculator()
{
_birthdays = new List<Birthday>();// <----- here is a dependency
}
...
修复:把它放在一个ctor中。
public class BirthdayCalculator
{
private readonly IList<Birthday> _birthdays;
public BirthdayCalculator(IList<Birthday> birthdays)
{
_birthdays = birthdays;
}
如果它将在 ctor 中 - 我每次使用课程时都必须发送它。
BirthdayCalculator
所以我在上课时必须保留它。这样做可以吗?我可以争辩说,在修复之后,仍然 -
IList<Birthday> _birthdays
不应该在那里(Birthday
在IList
) - 但它应该是IList<IBirthday>
。我对吗 ?
问题 #2 - 关于Liskov 替换:
派生类必须可以替代它们的基类
或更准确:
令 q(x) 是关于 T 类型的对象 x 的可证明性质。那么 q(y) 对于 S 类型的对象 y 应该为真,其中 S 是 T 的子类型。
(已经读过这个)
例子 :
public abstract class Account
{
public abstract void Deposit(double amount);
}
我有一堂课:
public class CheckingAccount : Account
{
public override void Deposit(double amount)
{ ...
_currentBalance += amount;
}
}
银行想开一个抵押账户——所以:
public class MortgageAccount : Account
{
public override void Deposit(double amount)
{
_currentBalance -= amount; //<-----notice the minus
}
}
当有一个函数接受抵押 Account
并做存款时,问题就出现了。
public class Bank
{
public void ReceiveMoney(Account account, double amount)
{
double oldBalance = account.CurrentBalance;
account.Deposit(amount); //oopssss?????
}
}
所以在这里,它违反了 LSP。
但 我不明白。
每个被覆盖的方法在被覆盖时都会执行不同的代码,因此它永远不会100 %可替换!
定义没有谈论“逻辑应该像基类一样继续(总是存入(添加)正数)”
例子:
如果CheckingAccount
class 和MortgageAccount
class 都存入正数但MortgageAccount
也登录到 db 怎么办?它仍然会破坏 LSP 吗?休息/不刹车 LSP 的边界是什么?
定义应该定义什么是边界。它并没有说什么。
我错过了什么?