SOLID принципы. Принцип инверсии зависимости

Содержание

Слайд 2

Принцип инверсии зависимости Модули верхнего уровня не должны зависеть от модулей

Принцип инверсии зависимости

Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны  зависеть от абстракций.

Слайд 3

Разбиение на слои В любой хорошо структурированной объектно-ориентированной архитектуре можно выделить

Разбиение на слои

В любой хорошо структурированной объектно-ориентированной архитектуре можно выделить ясно

очерченные слои, на каждом из которых предоставляется некий набор тесно связанных служб – с помощью четко определенных и контролируемых интерфейсов
Слайд 4

Слайд 5

Слайд 6

Инверсия владения

Инверсия владения

Слайд 7

Зависимость от абстракций Не должно быть переменных, в которых хранятся ссылки

Зависимость от абстракций

Не должно быть переменных, в которых хранятся ссылки на

конкретные классы.
Не должно быть классов, производных от конкретных классов.
Не должно быть методов, переопределяющих метод, реализованный в одном из базовых классов.
Слайд 8

Простой пример принципа DIP

Простой пример принципа DIP

Слайд 9

public class Button { private Lamp lamp; public void Poll() {

public class Button
{
private Lamp lamp;
public void Poll()
{
if (

/* какое-то условие */)
lamp.TurnOn();
}
}
Слайд 10

Слайд 11

const byte TERMOMETER = 0x86; const byte FURNACE = 0x87; const

const byte TERMOMETER = 0x86;
const byte FURNACE = 0x87;
const byte ENGAGE

= 1;
const byte DISENGAGE = 0;
void Regulate(double minTemp, double maxTemp)
{
for(;;)
{
while (in(TERMOMETER) > minTemp)
wait(1);
out(FURNACE,ENGAGE);
while (in(TERMOMETER) < maxTemp)
wait(1);
out(FURNACE,DISENGAGE);
}
}
Слайд 12

Слайд 13

void Regulate(Thermometer t, Heater h, double minTemp, double maxTemp) { for(;;)

void Regulate(Thermometer t, Heater h, double minTemp, double maxTemp)
{
for(;;)
{

while (t.Read() > minTemp)
wait(1);
h.Engage();
while (t.Read() < maxTemp)
wait(1);
h.Disengage();
}
}
Слайд 14

Принцип разделения интерфейсов (ISP) Клиенты не должны вынужденно зависеть от методов, которыми не пользуются

Принцип разделения интерфейсов (ISP)

Клиенты не должны вынужденно зависеть от методов, которыми не пользуются

Слайд 15

Загрязнение интерфейса public interface Door { void Lock(); void Unlock(); bool

Загрязнение интерфейса

public interface Door
{
void Lock();
void Unlock();
bool IsDoorOpen();
}

public class

Timer
{
public void Register(int timeout, TimerClient client)
{/* код */}
}
public interface TimerClient
{
void TimeOut();
}
Слайд 16

Слайд 17

Разделение клиентов означает разделение интерфейсов public class Timer { public void

Разделение клиентов означает разделение интерфейсов

public class Timer
{
public void Register(int timeout,

int timeOutId, TimerClient client)
{/* код */}
}
public interface TimerClient
{
void TimeOut(int timeOutID);
}
Слайд 18

Принцип разделения интерфейсов (Interface Segregation Principle) Клиенты не должны вынужденно зависеть от методов, которыми не пользуются

Принцип разделения интерфейсов (Interface Segregation Principle)

Клиенты не должны вынужденно зависеть от методов, которыми не пользуются

Слайд 19

Разделение путем делегирования

Разделение путем делегирования

Слайд 20

public interface TimedDoor : Door { void DoorTimeOut(int timeOutId); } public

public interface TimedDoor : Door
{
void DoorTimeOut(int timeOutId);
}
public class DoorTimerAdapter :

TimerClient
{
private TimedDoor timedDoor;
public DoorTimerAdapter(TimedDoor theDoor)
{
timedDoor = theDoor;
}
public virtual void TimeOut(int timeOutId)
{
timedDoor.DoorTimeOut(timeOutId);
}
}
Слайд 21

Разделение путем множественного наследования

Разделение путем множественного наследования

Слайд 22

public interface TimedDoor : Door, TimerClient { }

public interface TimedDoor : Door, TimerClient
{
}

Слайд 23

Пользовательский интерфейс банкомата

Пользовательский интерфейс банкомата

Слайд 24

Слайд 25

Слайд 26

public interface Transaction { void Execute(); } public interface DepositUI {

public interface Transaction
{
void Execute();
}
public interface DepositUI
{
void RequestDepositAmount();
}

public interface WithdrawalUI
{

void RequestWithdrawalAmount();
}

public interface TransferUI
{
void RequestTransferAmount();
}

public interface UI : DepositUI, WithdrawalUI, TransferUI
{
}

Слайд 27

public class DepositTransaction : Transaction { private DepositUI depositUI; public DepositTransaction(DepositUI

public class DepositTransaction : Transaction
{
private DepositUI depositUI;
public DepositTransaction(DepositUI ui)

{
depositUI = ui;
}
public virtual void Execute()
{
/* код */
depositUI.RequestDepositAmount();
/* код */
}
}

public class WithdrawalTransaction : Transaction
{
private WithdrawalUI withdrawalUI;
public WithdrawalTransaction(WithdrawalUI ui)
{
withdrawalUI = ui;
}
public virtual void Execute()
{
/* код */
withdrawalUI.RequestWithdrawalAmount();
/* код */
}
}

Слайд 28

public class TransferTransaction : Transaction { private TransferUI transferUI; public TransferTransaction(TransferUI

public class TransferTransaction : Transaction
{
private TransferUI transferUI;
public TransferTransaction(TransferUI ui)

{
transferUI = ui;
}
public virtual void Execute()
{
/* код */
transferUI.RequestTransferAmount();
/* код */
}
}