2. Связанность (coupling) определяет насколько
жестко один элемент (класс, модуль) связан с
другими элементами, либо каким
количеством данных о других элементах он
владеет.
Чем выше связанность, тем сложнее элемент
изменить, понять и повторно использовать.
Необходимо стремиться к низкой связанности
2
4. Связность или сцепление (cohesion) – мера
связанности и сфокусированности
обязанностей класса.
Считается, что элемент обладает высокой
степенью сцепления, если его обязанности
тесно связаны между собой и он не выполняет
непомерных объемов работ.
Нужно стараться достигать высокой степени
сцепления
4
7. SRP Принцип единственной
обязанности
OCP Принцип открытости/закрытости
LSP Принцип подстановки Лисков
ISP Принцип разделения интерфейсов
DIP Принцип инверсии зависимостей
7
8. У класса должна быть только одна причина
для изменения (одна обязанность)
Пример невыполнения SRP
8
12. Должна быть возможность вместо базового
типа подставить любой его подтип.
При нарушении LSP часто появляется
проверка типов во время выполнения (if или
switch по типам, is, as)
12
13. class Rectangle {
private Point topLeft;
private double width;
private double height;
public double Width {
get { return this.width; }
set { this.width = value; }
}
public double Height {
get { return this.height; }
set { this.height = value; }
}
}
class Square : Rectangle {
public new double Width {
set
{
base.Width = value;
base.Height = value;
}
}
public new double Height {
set {
base.Width = value;
base.Height = value;
}
}
}
13
14. void SetWidth(Rectangle r) {
r.Width = 32;
}
У Square будет побочный эффект, а у
Rectangle нет – нарушение LSP
14
15. В иерархию добавили метод расчета
площади – Area()
public void TestArea(Rectangle r) {
r.Width = 4;
r.Height = 5;
Debug.Assert(r.Area() == 20, "Неверная
площаль!");
}
15
16. Модули верхнего уровня не должны
зависеть от модулей нижнего уровня. И те и
другие должны зависеть от абстракции.
Абстракции не должна зависеть от
деталей, детали должны зависеть от
абстракций.
16
19. Клиент не должен вынужденно зависеть от
методов, которыми не пользуется.
Зависимость между классами должна быть
ограничена как можно более узким интерфейсом.
19
20. abstract class ServiceClient {
public string ServiceUri { get; set; }
public abstract void SendData(object data);
public abstract void Flush();
}
class HttpServiceClient : ServiceClient {
public override void SendData(object data) {...}
public override void Flush()
{
// Метод ничего не делает, но присутствует в классе
}
}
class BufferingHttpServiceClient : ServiceClient {
public override void SendData(object data) {...}
public override void Flush() {...}
}
20
21. abstract class ServiceClient {
public string ServiceUri { get; set; }
public abstract void SendData(object data);
}
abstract class BufferingServiceClient : ServiceClient {
public abstract void Flush();
}
class HttpServiceClient : ServiceClient {
public override void SendData(object data){ ... }
}
class BufferingHttpServiceClient : BufferingServiceClient {
public override void SendData(object data){ ... }
public override void Flush(){ ... }
}
21
22. Мартин Р. Мартин М. Принципы, паттерны
и методики гибкой разработки на языке C#.
– СПб.: Символ-Плюс, 2011. – 768 с., ил.
Ларман К. Применение UML 2.0 и шаблонов
проектирования. Практическое руководство. 3-е
издание. – Пер. с англ. – М.: ООО «И.Д.
Вильямс», 2013. – 736 с.: ил.
http://bit.ly/40n2uT
http://bit.ly/gGTAAv
http://bit.ly/14xRxW7
http://bit.ly/WmVJpH
22