これについて非常に多くの記事を読みましたが、まだ 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 が T のサブタイプである型 S のオブジェクト y に対して真でなければなりません。
(すでにこれを読んでいます)
例 :
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 とclassの両方MortgageAccount
が正の数をデポジットしていMortgageAccount
て、 db にもログを記録していたとしたら? それはまだ LSP を壊しますか? ブレーク/非ブレーキ LSP の境界は何ですか?
定義は、その境界が何であるかを定義する必要があります。そして、それについて何も言っていません。
私は何が欠けていますか?