Сегодня о последнем и очень важном принципе SOLID, инверсии зависимостей.

Определение принципа инверсии зависимостей из Википедии:

Модули высокого уровня не должны зависеть от модулей низкого уровня — отношения между ними должны быть результатом абстракции.

Другими словами, в классах и методах мы не должны использовать какие-либо имена конкретных классов, это должны быть только имена интерфейсов и абстрактных классов.

Кроме того, классы не должны наследовать от конкретных классов, а только от абстрактных классов и интерфейсов.

Что было бы, если бы высокоуровневые модули зависели от низкоуровневых?

Если, например, мы изменили что-то в классе, после которого наследуется другой класс, то эти изменения могли что-то выкинуть в наследующемся от него классе, поэтому использовать классы, зависящие от низкоуровневых модулей, было бы очень сложно, потому что, когда мы что-то меняем в этого класса нам, вероятно, придется что-то изменить в классе, после которого она наследуется.

Однако, если мы реверсируем эту зависимость, повторно использовать такие классы будет очень просто.

Посмотрим, как это выглядит на практике:

public void Pay(PayPal paypal)
{
//.....
}

Это пример метода, который реализует оплату PayPal, вы не можете написать что-то подобное, приведенный выше пример теперь зависит от класса PayPal

Это должно выглядеть так:

public void Pay(IPayPal paypal)
{
//.....
}

Теперь наш пример зависит от абстракции, т.е. от интерфейса IPayPal, теперь нам все равно, что происходит в низкоуровневых модулях, т.е. в предыдущем примере в PayPal > класс. Метод Pay просто реализует интерфейс IPayPal.

Это дает более или менее то, что мы можем изменить методы интерфейса IPayPal.

Такой подход также позволяет очень легко получить другие классы в некоторые библиотеки и использовать их в других проектах, если бы мы не использовали этот подход, нам пришлось бы перетаскивать все используемые нами классы или массу ссылок.

Давайте сделаем другой пример:

class Program
{
    static void Main(string[] args)
    {
        var bank= new Bank();
    }
}
 
public class Bank
{
    ...
    public Bank()
    {
        _pay=new Pay();
    }
 
    ...
}
public class Pay
{
    public void PayCard()
    {
        //pay with the card
    }
 
    public void PayPal()
    {
        //pay via PayPal
    }
}

В данном примере мы не имеем никакого влияния на то какие платежи будем использовать, высокоуровневый модуль это банк, а низкоуровневые платежи, в конструкторе сохраняется какие платежи мы будем использовать.

Как этот пример должен хорошо выглядеть? Более менее:

class Program
{
    static void Main(string[] args)
    {
        var pay= new Pay();
 
        var bank= new Bank(pay);
    }
}
 
public class Bank
{
    ...
    public Bank(IPay pay)
    {
        _pay=pay
    }
 
    ...
}
 
interface IPay
{
    void PayCard();
    void PayPal();
}
 
public class Pay,IPay
{
    public void PayCard()
    {
        //pay with the card
    }
 
    public void PayPal()
    {
        //pay via PayPal
    }
}

Теперь мы можем сами выбирать оплату, не углубляясь в низкоуровневые модули.

Резюме

Это все о принципе инверсии зависимостей.

Этот принцип связан с двумя очень важными паттернами, которые точно говорят вам, как избежать многоуровневых зависимостей и как облегчить написание многоуровневых зависимостей, из каких так называемых контейнеров эти паттерны включают внедрение зависимостей и инверсия управления. Оба описаны здесь.

Этот контент также можно найти в моем блоге https://steemit.com/solid/@slawas/solid-principles-5-dependency-inversion-principle

И в моем блоге devman: http://devman.pl/programtech/solid-principles-5-dependency-inversion-principle/

Стандартно напоминаю о бюллетене, в котором рассылаю уведомления о новых записях и дополнительную информацию о мире ИТ в целом.

И ОБЯЗАТЕЛЬНО присоединяйтесь к сообществу DevmanCommunity на фб, часть сообщества находится в одном месте

– сайт на фб: Devman.pl-Славомир Ковальски

— группа на фб: DevmanCommunity

Вы должны понять все незыблемые принципы сверху донизу, они вообще очень важны в программировании, благодаря им вы сможете вести большие проекты и делать их такими, чтобы их легко изменить, расширить, понять и т. д.

Спрашивайте, комментируйте в конце поста, делитесь им, оценивайте, делайте что хотите.