Upload
-
View
207
Download
6
Embed Size (px)
Citation preview
1
SOLID Принципы объектно-ориентированного дизайна
Польгун М.
2
Связанность (coupling) определяет насколько жестко один элемент (класс, модуль) связан с другими элементами, либо каким количеством данных о других элементах он владеет. Чем выше связанность, тем сложнее элемент изменить, понять и повторно использовать.
Необходимо стремиться к низкой связанности
3
Связанность
4
Связность или сцепление (cohesion) – мера связанности и сфокусированности обязанностей класса. Считается, что элемент обладает высокой степенью сцепления, если его обязанности тесно связаны между собой и он не выполняет непомерных объемов работ.
Нужно стараться достигать высокой степени сцепления
5
6
7
SRP Принцип единственной обязанности
OCP Принцип открытости/закрытости
LSP Принцип подстановки Лисков
ISP Принцип разделения интерфейсов
DIP Принцип инверсии зависимостей
SOLID
8
У класса должна быть только одна причина для изменения (одна обязанность)
SRP. Принцип единой обязанности
Пример невыполнения SRP
9
Выполнение SRP
10
Программные сущности (классы, модули, функции и т.п.) должны быть открыты для расширения, но закрыты для модификации
OCP. Принцип открытости/закрытости
Пример невыполнения OCP
11
Выполнение OCP
12
Должна быть возможность вместо базового типа подставить любой его подтип.
При нарушении LSP часто появляется проверка типов во время выполнения (if или switch по типам, is, as)
LSP. Принцип подстановки Лисков
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; } } }
Пример нарушения LSP
14
void SetWidth(Rectangle r) { r.Width = 32; }
У Square будет побочный эффект, а у Rectangle нет – нарушение LSP
15
В иерархию добавили метод расчета площади – Area()
public void TestArea(Rectangle r) { r.Width = 4; r.Height = 5;
Debug.Assert(r.Area() == 20, "Неверная площаль!");}
16
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракции.
Абстракции не должна зависеть от деталей, детали должны зависеть от абстракций.
DIP. Принцип инверсии зависимостей
17
18
19
Клиент не должен вынужденно зависеть от методов, которыми не пользуется.
Зависимость между классами должна быть ограничена как можно более узким интерфейсом.
ISP. Принцип разделения интерфейсов
20
Нарушение ISP 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() {...} }
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(){ ... }}
Соблюдение ISP
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
Информационные источники
23
Спасибо за внимание!