I read so many articles about this, but still I have 2 questions.
Question No. 1 - Regarding Inversion of Dependencies :
It states that high-level classes should not be dependent on low-level classes. Both should depend on abstractions. Abstractions should not depend on the details. Details should depend on abstractions.
eg:
public class BirthdayCalculator { private readonly List<Birthday> _birthdays; public BirthdayCalculator() { _birthdays = new List<Birthday>();
Fix: put it in ctor.
public class BirthdayCalculator { private readonly IList<Birthday> _birthdays; public BirthdayCalculator(IList<Birthday> birthdays) { _birthdays = birthdays; }
If it is in ctor, I will have to send it every time I use the class. Therefore, I will have to save this when calling the BirthdayCalculator class. is it ok to do so?
I can argue that after the fix, still - IList<Birthday> _birthdays should not be there ( Birthday in IList ) - but it should be like IList<IBirthday> . I'm right?
Question No. 2 - Regarding the replacement of Liskov :
derived classes must be substituted for base classes
or more precisely:
Let q (x) be a property provable with respect to objects x of type T. Then q (y) must be true for objects y of type S, where S is a subtype of T.
(already read this )
example:
public abstract class Account { public abstract void Deposit(double amount); }
I have a class:
public class CheckingAccount : Account { public override void Deposit(double amount) { ... _currentBalance += amount; } }
and the bank wants to open a Mortgage Account - like this:
public class MortgageAccount : Account { public override void Deposit(double amount) { _currentBalance -= amount;
The problem arises when there is a function that accepts mortage as Account and makes a deposit.
public class Bank { public void ReceiveMoney(Account account, double amount) { double oldBalance = account.CurrentBalance; account.Deposit(amount);
therefore, here he violates the LSP.
But I do not understand.
Each overridden method will execute different code when overriding, so it will never be replaced by 100%!
the definition did NOT say that "the logic should continue as in the base class (always add (add) positive numbers)"
Example:
What if the CheckingAccount class and the MortgageAccount class share positive numbers, but MortgageAccount also log to db? still interrupting LSP? What is the LSP gap / non-brake boundary?
the definition should determine whatis that border. and he says nothing about it.
What am I missing?