SlideShare a Scribd company logo
1 of 35
Download to read offline
Модифицируемость  
программных  систем
ДЗЮБА  ДМИТРИЙ  ВЛАДИМИРОВИЧ,  СТАРШИЙ  
ПРЕПОДАВАТЕЛЬ  КАФ.  806  
DDZUBA@YANDEX.RU
2
Требования  к  модифицируемости
Что  затрудняет  изменение  кода?
Класс  А
Класс  Б
Использует  Класс  А
Класс  В
Использует  Класс  А
Класс  Г
Использует  Класс  А
Класс  Д
Используется  Классом  А
Класс  Е
Используется  Классом  А
Класс  Ё
Используется  Классом  А
4
Локализация  модификаций
1. Поддержка  семантической  связанности.
Ответственности  модулей  разбиваются  на  стадии  проектирования,  т.к.  что  бы  каждая  
ответственность  попадала  внутрь  определенного  модуля  и  не  делилась.  Выделение  общих  
функций  в  отдельные  модули  (Framework).
2. Предвосхищение  ожидаемых  изменений.
На  стадии  проектирования  задаются  вопросы,  какие  изменения  в  системе  возможны?  Цель  
-­‐ что  бы  однотипные  изменения  приводили  к  доработкам  одних  и  тех  же  модулей.
3. Обобщение  модуля.  
Использование  модифицируемых  интерфейсов  (расширяемые  протоколы,  
интерпретируемый  формат  данных).  Модуль  разделяется  на  интерпретатор  внешних  
запросов  и  сам  модуль.  Позволяет  модифицировать  модуль  меняя  интерпретатор  внешних  
запросов  а  не  сам  модуль.  
4. Ограничение  модифицируемости.  
Для  каждого  модуля  на  стадии  проектирования  определяются  возможности  модификации.  
Что  дает  возможность  уменьшить  влияние  модификаций  (но  и  ухудшить  модифицируемость  
продукта).
Зависимости  между  модулями  [1/5]
Синтаксические  -­‐ сигнатуры  данных  производимых  модулем  А,  должны  соответствовать  
ожиданием  модуля  Б,  сигнатуры  вызываемых  методов  -­‐ аналогично.
Пример:
◦ Модуль  A вызывает  метод  “int  doHelloWorld(string   name)”
◦ Модуль  B реализует  метод  “int  doHelloWorld(string   name)”
5
6
Зависимости  между  модулями  [2/5]
Семантические  -­‐ смысл  данных  производимых  модулем  А,  совпадает  со  смыслом    ожидаемым  
модулем  Б,  аналогично  с  методами.
Пример:
◦ Модуль  A вызывает  метод  “int doHelloWorld(string name)”.  Где  имя  передается  в  
формате  «Имя Отчество Фамилия»
◦ Модуль  B реализует  метод  “int doHelloWorld(string name)” Где  имя  ожидается  в  
формате  «Имя Отчество Фамилия»
7
Зависимости  между  модулями  [3/5]
Последовательность  -­‐ если  определена  последовательность  в  которой  передаются  
данные,  то  она  должна  пониматься  одинакова  обеими  сторонами.  Так  же  если  второй  
вызов  может  идти  вслед  за  первым  в  установленный  промежуток  времени.
Пример
1.  Передается  запрос  на  открытие  сессии.
2.  Передаются  данные
3.  Получаются  данные
4.  Передается  запрос  на  закрытие  сессии.
8
Зависимости  между  модулями  [4/5]
1. Идентификация  интерфейса.  Модуль  Б  должен  знать  корректную  идентификацию  (имя)  
интерфейса  А.
Пример
Если  модуль  B  реализует  интерфейс  IHelloWorld.  То  модуль  А  должен  знать  что  это  интерфейс  
IHelloWorld.
2. Расположение  модуля  Что  бы  Б  запускался  правильно  он  должен  знать  откуда  будет  вызываться  
модуль  А.
Пример
При  вызове  .NET  Remoting необходимо  знать  URL хоста  сервиса.
9
Зависимости  между  модулями  [5/5]
1. Качество  данных.  Могут  быть  предположения  о  структуре  данных  (определенная  точность).
Пример
В бухгалтерской программе может быть заранее оговорено, что деньги имеют
точность 4 знака после запятой, что бы исключить расхождения из-за неверного
округления.
2. Существование  модуля.  Если  модуль  не  существует  то  другой  не  сможет  его  использовать.
Пример
В коде модуля А может быть явно прописана процедура создания экземпляра модуля
B (скажем вызов конструктора). Если бы нужный интерфейс реализовывался бы
другим модулем, то пришлось бы вызывать другой конструктор.
3. Управление  ресурсами.  
Модуль  должен  работать  с  ресурсами  на  основании  предположений  вызывающего  модуля.  Например,  
использовать  с  ним  общую  память.
10
Тактики:    Уменьшение  связанности модулей
1. Скрытие  внутреннего  поведения  модуля. Скрытие  внутренних  функций  в  модуле  с  
обеспечением  доступа  через  public  интерфейсы.
2. Уменьшение  путей  коммуникации. Уменьшение  числа  модулей  которые  разделяют  
информацию  с  текущим  модулем.  Это  уменьшает  связи  между  модулями.  И  позволяет  
уменьшить  эффект  каскадных  изменений.
3. Поддержка  ранее  созданных  интерфейсов.  В  случае  если  мы  зафиксировали  
интерфейс,  то  меняя  реализацию  вызываемого  модуля  мы  оставляем  вызывающий  
модуль  неизменным  (в  случае  если  не  меняется  семантика  данных,  качество  и  т.д.)
11
Тактики:  Применение  посредников
Применение  модулей-­‐посредников  позволяет  оградить  один  модуль  от  модификаций  
другого  (в  случае,  если  не  меняется  семантика  данных).  
Типы  посредников:
◦ Изменение  данных. Создаются  словари  для  преобразования  данных  из  одного  формата  в  другой  
формат.  
◦ Изменение  сервисов. Façade,  bridge,  mediator,  strategy,proxy  and  factory  позволяют  создать  и  
работать  с  промежуточным   слоем.
◦ Изменение  названия  интерфейса. Паттерн  Broker позволяет  не  менять  вызывающий  модуль,  если  
на  сервере  поменялось  название  интерфейса  путем  настроек  брокера.  
◦ Изменение  места  расположения  сервисов. Использование  Name-­‐серверов,  отвечающих  за  
определение  места  положения  сервиса  по  имени.
◦ Изменение  метода  управления  ресурсами. Применение  централизованного  модуля  управления  
ресурсами  позволяет  всем  модулям  работать  с  ресурсами  одинаково  (например,  может  быть  
единый  модуль  создающий  потоки  выполнения  и  гарантирующий  что  количество  потоков  не  
будет  превышено).
◦ Существование  модуля. Factory  может  создавать  как  сам  модуль  так  и  заглушку.
12
Тактики:  Отложенное  связывание
1. Runtime  registration  использование  механизмов  plugin.
2. Configuration   files  конфигурирование  системы  при  старте.
3. Polymorphism   использование  наследования  для  переопределения  классов.
4. Component  replacement  подмена  компонент  (библиотек)  при  загрузки  системы.
5. Строгое  соблюдение  протокола  позволяет  связывать  в  runtime  независимые  процессы.
Уровни  зрелости  модульной  структуры  
ПО
1. Level  1:  Ad  Hoc  
Ни  какой  специальной  модульной  структуры  нет.
Плюсы:  просто  и  дешево.
2. Level  2:  Modules  
Модули  отделены  от  друг  друга,  имеют  версию  и  свой  идентификатор.
Плюсы:  отделение  модулей  от  кода,  упрощение  работы  с  зависимостями   в  коде  и  версионной  сборки.
3. Level  3:  Modularity  
Модуль  может  манятся  автономно,  не  зависимо  от  других  модулей.  Модуль  описывается  своим  «контрактом».
Плюсы:  Возможность  предсказать  сложность  внесения   изменений  в  систему.  
4. Level  4:  Loose  coupling  
Разделение  интерфейса   и  реализации.  
Плюсы:  Независимость   поставщика  и  получателя  интерфейса.  
5. Level  5:  Devolution  (ограниченная  автономия)
Артефакты  модулей  храниться  в  репозиториях.  Модули  собираются  из  артефактов  в  зависимости   от  необходимых  сервисов.
Плюсы: уменьшение   дублирования,  улучшенная  независимость   модулей.
6. Level  6:  Dynamism  
Динамическое   управление  жизненным  циклом  модуля.  Поддержка  операций  добавления./              изменения   модуля.
Плюсы: Динамическое   развитие  системы  и  управление.
13
Объектно-­‐ориентированное  
программирование
Абстракция  выделяет  существенные  характеристики  некоторого  объекта,  
отличающие  его  от  всех  других  видов  объектов  и,  таким  образом,  четко  определяет  
его  концептуальные  границы  с  точки  зрения  наблюдателя.
1. Абстракция  сущности
Объект  представляет  собой  полезную  модель  некой  сущности  в  предметной  области  
2. Абстракция  поведения
Объект  состоит  из  обобщенного  множества  операций  
3. Абстракция  виртуальной  машины
Объект  группирует  операции,  которые  либо  вместе  используются  более  высоким  
уровнем  управления,  либо  сами  используют  некоторый  набор  операций  более  низкого  
уровня  
4. Произвольная  абстракция
Объект  включает  в  себя  набор  операций,  не  имеющих  друг  с  другом  ничего  общего  
Абстракция  сущности
Domain  Driven  Design
Подход,  позволяющий  быстро  
проектировать  стабильную  архитектуру  
приложения,  основываясь  на  терминах  
предметной  области.
Основные  способы  определения  модулей:
◦ Layers
◦ Entity
◦ Value  Object
◦ Services
◦ Repository
15
Слои  программного  обеспечения
Разделение  программного  обеспечения  на  
слои  согласно  выполняемым  функциям  с  
точки  зрения  программного  обеспечения.
Например:  
◦ Слой  пользовательского  интерфейса;
◦ Слой  бизнес-­‐логики;
◦ Слой  информации  о  домене  сущностей;
◦ Слой  доступа  к  данным;
Должно  быть  четкое  разделение  слоев.
Должны  быть  определены  правила  
взаимодействия  слоев  (интерфейсы).
16
Сущности  – объекты  реального  мира
Представляют  объекты  реального  мира;
Обладают  идентификацией  (например,  
номер  паспорта  +  дата  и  место  выдачи  для  
человека)
Обладают  явно  выраженным  жизненным  
циклом  (процедурой  создания,  удаления,  
изменения  состояния)
Обладают  поведением.
17
Объект-­‐значение
Не  обладают  идентификацией  
Могут  копироваться  и  передаваться  от  
функции  к  функции  без  ограничений.
Не  обладают  жизненным  циклом
Создаются  когда  надо  и  удаляются,  когда  ни  
кем  не  используются
Зачастую  не  меняют  своих  атрибутов
Могут  быть  доступны  для  коллективного  
доступа  из  разных  частей  программы.
Атрибуты  составляющие  Value  Object  
должны  быть  концептуально  полными  
(соответствовать  какой-­‐либо  абстракции)
18
Сервисы
Основные  свойства:
◦ Описывают  процессы,  работающие  с  Entity и  Value  Object в  терминах  предметной  области
◦ Не  имеют  состояния;
◦ Не  заменяют  операции,  которые  принадлежат  Entity,  а  дополняет  их.  Обычно  сервис  является  важным  
процессом  с  точки  зрения  домена;
Разделяют  сервисы,  принадлежащие  уровню  домена  и  сервисы,  принадлежащие  
инфраструктуре  (например,  доступ  к  данным)
Command  Query  Separation
“every  method  should  either  be  a  command  that  performs  an  action,  or  a  query  that  returns  data  to  
the  caller,  but  not  both.  In  other  words,  asking  a  question  should  not  change  the  answer”  
Bertrand  Meyer
19
Модули
1. Modules
Состоят  из  элементов,  логически  связанных  друг  с  другом.
2. Агрегаты
Группа  связанных  объектов,  которые  могут  рассматриваться  как  одно  
целое
3. Фабрики
Инкапсулирую  процесс  создания  сложных  объектов  или  группы  объектов
4. Репозитории
Реализуют  логику  получения  ссылки  на  объекты  предметной  области  по  
разным  критериям
20
21
Итого
SOLID
как  организовать  структуру  классов?
• SRP  Принцип  единственной  обязанности.
На  каждый  объект  должна  быть  возложена  одна  единственная  обязанность.  
• OCP  Принцип  открытости/закрытости.
Программные  сущности  должны  быть  открыты  для  расширения,  но  закрыты  для  изменения.  
• LSP  Принцип  подстановки  Барбары  Лисков.
Объекты  в  программе  могут  быть  заменены  их  наследниками  без  изменения  свойств  
программы.  
• ISP  Принцип  разделения  интерфейса.
Много  специализированных  интерфейсов  лучше,  чем  один  универсальный.  
• DIP  Принцип  инверсии  зависимостей.
Зависимости  внутри  системы  строятся  на  основе  абстракций.  Модули  верхнего  уровня  не  
зависят  от  модулей  нижнего  уровня.  Абстракции  не  должны  зависеть  от  деталей.  Детали  
должны  зависеть  от  абстракций.  
SRP:  Single  Responsibility  Principle  
(принцип  единственной  обязанности)
Не  должно  существовать  более  одного  
мотива  для  изменения  данного  класса
class  01  SRP  OFF
Customer
+   GetName():  const  char*
Order
Product
+   CalculateTax():  double
+   GetName():  const  char*
+   GetPrice():  double
+   MakeReservation():  bool
class  01  SRP  ON
Customer
+   GetName():  const  char*
Order
Product
+   GetName():  const  char*
+   GetPrice():  double
TaxCalculator
+   CalculateTax(Product):  double
ProductReservation
+   ReserveProduct(Product):  bool
*антипаттерн
OCP:  Open/Closed  Principle  (принцип  
открытия/закрытия)
Объекты  проектирования  (классы,  функции,  
модули  и  т.д.)  должны  быть  открыты  для  
расширения,  но  закрыты  для  модификации.
class  02  OCP  OFF
Customer
+   GetName():  const  char*
Order
Product
+   GetName():  const  char*
+   GetPrice():  double
TaxCalculator
+   CalculateTax(Product):  double
ProductReservation
+   ReserveProduct(Product):  bool
Catalogue
+   FindByName(const  char*):  Product
class  02  OCP  ON
Customer
+   GetName():  const  char*
Order
Product
+   GetName():  const  char*
+   GetPrice():  double
TaxCalculator
+   CalculateTax(Product):  double
ProductReservation
+   ReserveProduct(Product):  boolCatalogue
+   FindByName(IFindSpecification):  Product
«interface»
IFindSpecification
+   isIt(Product):  bool
FindByNameSpecification
+   isIt(Product):  bool
FindByGroupSpecification
+   isIt(Product):  bool
*антипаттерн
LSP:  Liskov Substitution  Principle  (принцип  замещения  
Лисков)
пример  SOLID_LSP
Функции,  которые  используют  ссылки  на  базовые  классы,  должны  иметь  
возможность  использовать  объекты  производных  классов,  не  зная  об  этом
class Rectangle
{
protected:
int width;
int height;
public:
Rectangle(int w, int h) : width(w), height(h) {};
virtual void SetWidth(int value) { width = value; }
virtual void SetHeight(int value) { height = value;
}
virtual int GetSquare() { return width * height; }
};
class Square : public Rectangle
{
public:
Square(int w, int h) :
Rectangle(w,w) {};
virtual void SetWidth(int value) {
width = value; height = value; }
virtual void SetHeight(int value) {
width = value; height = value; }
};
LSP:  Нарушение  принципа  LSP  (class  diagram)
антипаттерн
class  03  LSP
Rectangle
#   height:  int
#   width:  int
+   GetSquare():  int
+   Rectangle(int,  int)
+   SetHeight(int):  void
+   SetWidth(int):  void
Square
+   SetHeight(int):  void
+   SetWidth(int):  void
+   Square(int,  int)
ISP:  Interface  Segregation  Principle  (принцип  
изоляции  интерфейса)
пример   SOLID_ISP
Клиент  не  должен  вынужденно  зависеть  от  элементов  интерфейса,  которые  он  не  
использует.
Другими  словами  этот  принцип  можно  сформулировать  так:  зависимость  между  классами  
должна  быть  ограничена  как  можно  более  узким  интерфейсом.
class IBusinessMenu
{
protected:
virtual const char* GetFirstItem() =0 ;
virtual const char* GetSecondItem() =0;
virtual const char* GetCompot() =0 ;
public:
void PrintMenu()
{
if (GetFirstItem() != nullptr) std::cout << "Item:" << GetFirstItem() << std::endl;
if (GetSecondItem() != nullptr) std::cout << "Item:" << GetSecondItem() << std::endl;
if (GetCompot() != nullptr) std::cout << "Item:" << GetCompot() << std::endl;
}
};
ISP:  Class  Diagram
антипаттерн
class  04  ISP
CoffeMenu
-­   bulka:  std::string
-­   coffe:  std::string
+   CoffeMenu(std::string,  std::string)
#   GetCompot():  char*
#   GetFirstItem():  char*
#   GetSecondItem():  char*
BusinessMenu
-­   compot:  std::string
-­   first:  std::string
-­   second:  std::string
+   BusinessMenu(std::string,  std::string,  std::string)
#   GetCompot():  char*
#   GetFirstItem():  char*
#   GetSecondItem():  char*
IBusinessMenu
#   GetCompot():  char*
#   GetFirstItem():  char*
#   GetSecondItem():  char*
+   PrintMenu():  void
ISP:  Sequence  Diagram
антипаттерн
sd  04  ISP
BusinessMenu CoffeMenu
main
PrintMenu()
PrintMenu()
DIP:  Dependency  Inversion  Principle  
(принцип  обращения  зависимости)
пример SOLID_DIP
Модули  верхних  уровней  не  должны  зависеть  от  модулей  нижних  уровней.  Оба  типа  
модулей  должны  зависеть  от  абстракций.  Абстракции  не  должны  зависеть  от  деталей.  
Детали  должны  зависеть  от  абстракций.
class IItem
{
public:
virtual void print() = 0;
};
class Menu
{
private:
std::vector<IItem*> items;
public:
void add(IItem *i) {
items.insert(items.end(),i); }
void menu() {
for (auto i : items) i->print(); }
};Стратегия  Menu  применяется  к  
интерфейсу  IItem.  Этим  мы  устранили  
недостатки  предыдущего  варианта.
DIP:  Class  Diagram
class  05  DIP
ItemBulka
+   print():  void
IItem
+   print():  void
ItemCoffe
+   print():  void
Menu
-­   items:  std::vector<IItem*>
+   add(IItem*):  void
+   menu():  void
DIP:  Sequence  Diagram
sd  05  DIP
IItemMenu
main
ItemBulka
ItemCoffe
menu()
add(IItem*)
add(IItem*)
*print()
Tell  Don’t  Ask
пример SOLID_TDA,  CQS
Один  из  основополагающих  принципов  ООП:  Необходимо  
делегировать  объекту  действия,  вместо  того,  что  запрашивать  его  
детали  реализации.Это  помогает  достичь  многократного  
использование  класса  (поскольку  ни  кто  не  знает  его  деталей  
реализации).
Command  Query  Separation  – принцип  разделение  методов,  
которые  выполняют  какие-­‐либо  действия  (tell)  и  методов,  
которые  осуществляют  запросы  данных  (ask).
Law  of  Demeter  – объект  может  вызывать  методы  только:
• Себя
• Своих  параметров
• Объектов,  созданных  внутри  метода
Модифицируемость  vs  Performance
Разделение  данных  на  домены  ведет  к  увеличению  
распределенности  объектов  между  сервисами,  что  ухудшает  
производительность.
Разделение  системы  на  слои,  увеличивает  количество  
преобразований  данных,  что  так  же  отрицательно  влияет  на  
производительность.
Использование  операций  в  терминах  домена  приводит  к  
тому,  что  появляется  дополнительное  преобразование  
данных  из  внутренней  модели  во  внешнюю.  Что  так  же  
отрицательно  влияет  на  производительность.
34
Спасибо!

More Related Content

What's hot

чмв лабораторная №3
чмв   лабораторная №3чмв   лабораторная №3
чмв лабораторная №3
student_kai
 
чмв лекция №5
чмв   лекция №5чмв   лекция №5
чмв лекция №5
student_kai
 
чмв лекция №6
чмв   лекция №6чмв   лекция №6
чмв лекция №6
student_kai
 
07 Архитектура информационных систем. Принципы GRASP
07 Архитектура информационных систем. Принципы GRASP07 Архитектура информационных систем. Принципы GRASP
07 Архитектура информационных систем. Принципы GRASP
Edward Galiaskarov
 

What's hot (20)

C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.
 
чмв лабораторная №3
чмв   лабораторная №3чмв   лабораторная №3
чмв лабораторная №3
 
CompanyMedia-Next - Architecture (Vladimir Panov, 26.12.2011)
CompanyMedia-Next - Architecture (Vladimir Panov, 26.12.2011)CompanyMedia-Next - Architecture (Vladimir Panov, 26.12.2011)
CompanyMedia-Next - Architecture (Vladimir Panov, 26.12.2011)
 
Диаграммы композитной структуры, коммуникации и пакетов
Диаграммы композитной структуры, коммуникации и пакетовДиаграммы композитной структуры, коммуникации и пакетов
Диаграммы композитной структуры, коммуникации и пакетов
 
Silverlight 5
Silverlight 5Silverlight 5
Silverlight 5
 
чмв лекция №5
чмв   лекция №5чмв   лекция №5
чмв лекция №5
 
чмв лекция №6
чмв   лекция №6чмв   лекция №6
чмв лекция №6
 
МиСПИСиТ (структура)
МиСПИСиТ (структура)МиСПИСиТ (структура)
МиСПИСиТ (структура)
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
 
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
 
07 Архитектура информационных систем. Принципы GRASP
07 Архитектура информационных систем. Принципы GRASP07 Архитектура информационных систем. Принципы GRASP
07 Архитектура информационных систем. Принципы GRASP
 
Сидристый Станислав: Паттерны и антипаттерны BDD
Сидристый Станислав: Паттерны и антипаттерны BDDСидристый Станислав: Паттерны и антипаттерны BDD
Сидристый Станислав: Паттерны и антипаттерны BDD
 
МиСПИСиТ (разработка программного модуля)
МиСПИСиТ (разработка программного модуля)МиСПИСиТ (разработка программного модуля)
МиСПИСиТ (разработка программного модуля)
 
МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4
 
Введение в язык программирования «Java»
Введение в язык программирования «Java»Введение в язык программирования «Java»
Введение в язык программирования «Java»
 
МиСПИСиТ (введение)
МиСПИСиТ (введение)МиСПИСиТ (введение)
МиСПИСиТ (введение)
 
Составные части объектного подхода
Составные части объектного подходаСоставные части объектного подхода
Составные части объектного подхода
 
Itgm #9. dmn. как моделировать принимаемые решения
Itgm #9. dmn. как моделировать принимаемые решенияItgm #9. dmn. как моделировать принимаемые решения
Itgm #9. dmn. как моделировать принимаемые решения
 
МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7
 

Similar to Модифицируемость программных систем

13 расширенные возможности корпоративных приложений, основы субд
13 расширенные возможности корпоративных приложений, основы субд13 расширенные возможности корпоративных приложений, основы субд
13 расширенные возможности корпоративных приложений, основы субд
KewpaN
 
9 структура компонентных приложений
9 структура компонентных приложений9 структура компонентных приложений
9 структура компонентных приложений
KewpaN
 
Konspekt
KonspektKonspekt
Konspekt
Artem
 
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
camp_drupal_ua
 
C++ осень 2012 лекция 8
C++ осень 2012 лекция 8C++ осень 2012 лекция 8
C++ осень 2012 лекция 8
Technopark
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8
Technopark
 

Similar to Модифицируемость программных систем (20)

Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»
 
Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений» Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
 
Шаблоны проектирования в Magento
Шаблоны проектирования в MagentoШаблоны проектирования в Magento
Шаблоны проектирования в Magento
 
13 расширенные возможности корпоративных приложений, основы субд
13 расширенные возможности корпоративных приложений, основы субд13 расширенные возможности корпоративных приложений, основы субд
13 расширенные возможности корпоративных приложений, основы субд
 
9 структура компонентных приложений
9 структура компонентных приложений9 структура компонентных приложений
9 структура компонентных приложений
 
JavaScript Design Patterns overview by Ksenia Redunova
JavaScript Design Patterns overview by Ksenia RedunovaJavaScript Design Patterns overview by Ksenia Redunova
JavaScript Design Patterns overview by Ksenia Redunova
 
SOLID – принципы объектно-ориентированного дизайна
SOLID – принципы объектно-ориентированного дизайнаSOLID – принципы объектно-ориентированного дизайна
SOLID – принципы объектно-ориентированного дизайна
 
MW
MWMW
MW
 
Genome
GenomeGenome
Genome
 
Распределённые приложения. Часть 1. «Клиент и ядро бизнес-логики»
Распределённые приложения. Часть 1.
«Клиент и ядро бизнес-логики»Распределённые приложения. Часть 1.
«Клиент и ядро бизнес-логики»
Распределённые приложения. Часть 1. «Клиент и ядро бизнес-логики»
 
Inroducing SAP ABAP - Presentation with basics SAP ABAP
Inroducing SAP ABAP - Presentation with basics SAP ABAPInroducing SAP ABAP - Presentation with basics SAP ABAP
Inroducing SAP ABAP - Presentation with basics SAP ABAP
 
Konspekt
KonspektKonspekt
Konspekt
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
 
шаблоны проектирования
шаблоны проектированияшаблоны проектирования
шаблоны проектирования
 
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
 
ASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVC
 
C++ осень 2012 лекция 8
C++ осень 2012 лекция 8C++ осень 2012 лекция 8
C++ осень 2012 лекция 8
 
Стандарты и соглашения в сложных ООП-приложениях
Стандарты и соглашения в сложных ООП-приложенияхСтандарты и соглашения в сложных ООП-приложениях
Стандарты и соглашения в сложных ООП-приложениях
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8
 

More from Dima Dzuba

Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Dima Dzuba
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4sts
Dima Dzuba
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10
Dima Dzuba
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9
Dima Dzuba
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8
Dima Dzuba
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7
Dima Dzuba
 

More from Dima Dzuba (20)

Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16
 
Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14
 
Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6
 
Производительность программных систем
Производительность программных системПроизводительность программных систем
Производительность программных систем
 
Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01
 
МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6
 
МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3
 
МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2
 
МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1
 
Решение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системРешение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных систем
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4sts
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7
 

Модифицируемость программных систем

  • 1. Модифицируемость   программных  систем ДЗЮБА  ДМИТРИЙ  ВЛАДИМИРОВИЧ,  СТАРШИЙ   ПРЕПОДАВАТЕЛЬ  КАФ.  806   DDZUBA@YANDEX.RU
  • 3. Что  затрудняет  изменение  кода? Класс  А Класс  Б Использует  Класс  А Класс  В Использует  Класс  А Класс  Г Использует  Класс  А Класс  Д Используется  Классом  А Класс  Е Используется  Классом  А Класс  Ё Используется  Классом  А
  • 4. 4 Локализация  модификаций 1. Поддержка  семантической  связанности. Ответственности  модулей  разбиваются  на  стадии  проектирования,  т.к.  что  бы  каждая   ответственность  попадала  внутрь  определенного  модуля  и  не  делилась.  Выделение  общих   функций  в  отдельные  модули  (Framework). 2. Предвосхищение  ожидаемых  изменений. На  стадии  проектирования  задаются  вопросы,  какие  изменения  в  системе  возможны?  Цель   -­‐ что  бы  однотипные  изменения  приводили  к  доработкам  одних  и  тех  же  модулей. 3. Обобщение  модуля.   Использование  модифицируемых  интерфейсов  (расширяемые  протоколы,   интерпретируемый  формат  данных).  Модуль  разделяется  на  интерпретатор  внешних   запросов  и  сам  модуль.  Позволяет  модифицировать  модуль  меняя  интерпретатор  внешних   запросов  а  не  сам  модуль.   4. Ограничение  модифицируемости.   Для  каждого  модуля  на  стадии  проектирования  определяются  возможности  модификации.   Что  дает  возможность  уменьшить  влияние  модификаций  (но  и  ухудшить  модифицируемость   продукта).
  • 5. Зависимости  между  модулями  [1/5] Синтаксические  -­‐ сигнатуры  данных  производимых  модулем  А,  должны  соответствовать   ожиданием  модуля  Б,  сигнатуры  вызываемых  методов  -­‐ аналогично. Пример: ◦ Модуль  A вызывает  метод  “int  doHelloWorld(string   name)” ◦ Модуль  B реализует  метод  “int  doHelloWorld(string   name)” 5
  • 6. 6 Зависимости  между  модулями  [2/5] Семантические  -­‐ смысл  данных  производимых  модулем  А,  совпадает  со  смыслом    ожидаемым   модулем  Б,  аналогично  с  методами. Пример: ◦ Модуль  A вызывает  метод  “int doHelloWorld(string name)”.  Где  имя  передается  в   формате  «Имя Отчество Фамилия» ◦ Модуль  B реализует  метод  “int doHelloWorld(string name)” Где  имя  ожидается  в   формате  «Имя Отчество Фамилия»
  • 7. 7 Зависимости  между  модулями  [3/5] Последовательность  -­‐ если  определена  последовательность  в  которой  передаются   данные,  то  она  должна  пониматься  одинакова  обеими  сторонами.  Так  же  если  второй   вызов  может  идти  вслед  за  первым  в  установленный  промежуток  времени. Пример 1.  Передается  запрос  на  открытие  сессии. 2.  Передаются  данные 3.  Получаются  данные 4.  Передается  запрос  на  закрытие  сессии.
  • 8. 8 Зависимости  между  модулями  [4/5] 1. Идентификация  интерфейса.  Модуль  Б  должен  знать  корректную  идентификацию  (имя)   интерфейса  А. Пример Если  модуль  B  реализует  интерфейс  IHelloWorld.  То  модуль  А  должен  знать  что  это  интерфейс   IHelloWorld. 2. Расположение  модуля  Что  бы  Б  запускался  правильно  он  должен  знать  откуда  будет  вызываться   модуль  А. Пример При  вызове  .NET  Remoting необходимо  знать  URL хоста  сервиса.
  • 9. 9 Зависимости  между  модулями  [5/5] 1. Качество  данных.  Могут  быть  предположения  о  структуре  данных  (определенная  точность). Пример В бухгалтерской программе может быть заранее оговорено, что деньги имеют точность 4 знака после запятой, что бы исключить расхождения из-за неверного округления. 2. Существование  модуля.  Если  модуль  не  существует  то  другой  не  сможет  его  использовать. Пример В коде модуля А может быть явно прописана процедура создания экземпляра модуля B (скажем вызов конструктора). Если бы нужный интерфейс реализовывался бы другим модулем, то пришлось бы вызывать другой конструктор. 3. Управление  ресурсами.   Модуль  должен  работать  с  ресурсами  на  основании  предположений  вызывающего  модуля.  Например,   использовать  с  ним  общую  память.
  • 10. 10 Тактики:    Уменьшение  связанности модулей 1. Скрытие  внутреннего  поведения  модуля. Скрытие  внутренних  функций  в  модуле  с   обеспечением  доступа  через  public  интерфейсы. 2. Уменьшение  путей  коммуникации. Уменьшение  числа  модулей  которые  разделяют   информацию  с  текущим  модулем.  Это  уменьшает  связи  между  модулями.  И  позволяет   уменьшить  эффект  каскадных  изменений. 3. Поддержка  ранее  созданных  интерфейсов.  В  случае  если  мы  зафиксировали   интерфейс,  то  меняя  реализацию  вызываемого  модуля  мы  оставляем  вызывающий   модуль  неизменным  (в  случае  если  не  меняется  семантика  данных,  качество  и  т.д.)
  • 11. 11 Тактики:  Применение  посредников Применение  модулей-­‐посредников  позволяет  оградить  один  модуль  от  модификаций   другого  (в  случае,  если  не  меняется  семантика  данных).   Типы  посредников: ◦ Изменение  данных. Создаются  словари  для  преобразования  данных  из  одного  формата  в  другой   формат.   ◦ Изменение  сервисов. Façade,  bridge,  mediator,  strategy,proxy  and  factory  позволяют  создать  и   работать  с  промежуточным   слоем. ◦ Изменение  названия  интерфейса. Паттерн  Broker позволяет  не  менять  вызывающий  модуль,  если   на  сервере  поменялось  название  интерфейса  путем  настроек  брокера.   ◦ Изменение  места  расположения  сервисов. Использование  Name-­‐серверов,  отвечающих  за   определение  места  положения  сервиса  по  имени. ◦ Изменение  метода  управления  ресурсами. Применение  централизованного  модуля  управления   ресурсами  позволяет  всем  модулям  работать  с  ресурсами  одинаково  (например,  может  быть   единый  модуль  создающий  потоки  выполнения  и  гарантирующий  что  количество  потоков  не   будет  превышено). ◦ Существование  модуля. Factory  может  создавать  как  сам  модуль  так  и  заглушку.
  • 12. 12 Тактики:  Отложенное  связывание 1. Runtime  registration  использование  механизмов  plugin. 2. Configuration   files  конфигурирование  системы  при  старте. 3. Polymorphism   использование  наследования  для  переопределения  классов. 4. Component  replacement  подмена  компонент  (библиотек)  при  загрузки  системы. 5. Строгое  соблюдение  протокола  позволяет  связывать  в  runtime  независимые  процессы.
  • 13. Уровни  зрелости  модульной  структуры   ПО 1. Level  1:  Ad  Hoc   Ни  какой  специальной  модульной  структуры  нет. Плюсы:  просто  и  дешево. 2. Level  2:  Modules   Модули  отделены  от  друг  друга,  имеют  версию  и  свой  идентификатор. Плюсы:  отделение  модулей  от  кода,  упрощение  работы  с  зависимостями   в  коде  и  версионной  сборки. 3. Level  3:  Modularity   Модуль  может  манятся  автономно,  не  зависимо  от  других  модулей.  Модуль  описывается  своим  «контрактом». Плюсы:  Возможность  предсказать  сложность  внесения   изменений  в  систему.   4. Level  4:  Loose  coupling   Разделение  интерфейса   и  реализации.   Плюсы:  Независимость   поставщика  и  получателя  интерфейса.   5. Level  5:  Devolution  (ограниченная  автономия) Артефакты  модулей  храниться  в  репозиториях.  Модули  собираются  из  артефактов  в  зависимости   от  необходимых  сервисов. Плюсы: уменьшение   дублирования,  улучшенная  независимость   модулей. 6. Level  6:  Dynamism   Динамическое   управление  жизненным  циклом  модуля.  Поддержка  операций  добавления./              изменения   модуля. Плюсы: Динамическое   развитие  системы  и  управление. 13
  • 14. Объектно-­‐ориентированное   программирование Абстракция  выделяет  существенные  характеристики  некоторого  объекта,   отличающие  его  от  всех  других  видов  объектов  и,  таким  образом,  четко  определяет   его  концептуальные  границы  с  точки  зрения  наблюдателя. 1. Абстракция  сущности Объект  представляет  собой  полезную  модель  некой  сущности  в  предметной  области   2. Абстракция  поведения Объект  состоит  из  обобщенного  множества  операций   3. Абстракция  виртуальной  машины Объект  группирует  операции,  которые  либо  вместе  используются  более  высоким   уровнем  управления,  либо  сами  используют  некоторый  набор  операций  более  низкого   уровня   4. Произвольная  абстракция Объект  включает  в  себя  набор  операций,  не  имеющих  друг  с  другом  ничего  общего  
  • 15. Абстракция  сущности Domain  Driven  Design Подход,  позволяющий  быстро   проектировать  стабильную  архитектуру   приложения,  основываясь  на  терминах   предметной  области. Основные  способы  определения  модулей: ◦ Layers ◦ Entity ◦ Value  Object ◦ Services ◦ Repository 15
  • 16. Слои  программного  обеспечения Разделение  программного  обеспечения  на   слои  согласно  выполняемым  функциям  с   точки  зрения  программного  обеспечения. Например:   ◦ Слой  пользовательского  интерфейса; ◦ Слой  бизнес-­‐логики; ◦ Слой  информации  о  домене  сущностей; ◦ Слой  доступа  к  данным; Должно  быть  четкое  разделение  слоев. Должны  быть  определены  правила   взаимодействия  слоев  (интерфейсы). 16
  • 17. Сущности  – объекты  реального  мира Представляют  объекты  реального  мира; Обладают  идентификацией  (например,   номер  паспорта  +  дата  и  место  выдачи  для   человека) Обладают  явно  выраженным  жизненным   циклом  (процедурой  создания,  удаления,   изменения  состояния) Обладают  поведением. 17
  • 18. Объект-­‐значение Не  обладают  идентификацией   Могут  копироваться  и  передаваться  от   функции  к  функции  без  ограничений. Не  обладают  жизненным  циклом Создаются  когда  надо  и  удаляются,  когда  ни   кем  не  используются Зачастую  не  меняют  своих  атрибутов Могут  быть  доступны  для  коллективного   доступа  из  разных  частей  программы. Атрибуты  составляющие  Value  Object   должны  быть  концептуально  полными   (соответствовать  какой-­‐либо  абстракции) 18
  • 19. Сервисы Основные  свойства: ◦ Описывают  процессы,  работающие  с  Entity и  Value  Object в  терминах  предметной  области ◦ Не  имеют  состояния; ◦ Не  заменяют  операции,  которые  принадлежат  Entity,  а  дополняет  их.  Обычно  сервис  является  важным   процессом  с  точки  зрения  домена; Разделяют  сервисы,  принадлежащие  уровню  домена  и  сервисы,  принадлежащие   инфраструктуре  (например,  доступ  к  данным) Command  Query  Separation “every  method  should  either  be  a  command  that  performs  an  action,  or  a  query  that  returns  data  to   the  caller,  but  not  both.  In  other  words,  asking  a  question  should  not  change  the  answer”   Bertrand  Meyer 19
  • 20. Модули 1. Modules Состоят  из  элементов,  логически  связанных  друг  с  другом. 2. Агрегаты Группа  связанных  объектов,  которые  могут  рассматриваться  как  одно   целое 3. Фабрики Инкапсулирую  процесс  создания  сложных  объектов  или  группы  объектов 4. Репозитории Реализуют  логику  получения  ссылки  на  объекты  предметной  области  по   разным  критериям 20
  • 22. SOLID как  организовать  структуру  классов? • SRP  Принцип  единственной  обязанности. На  каждый  объект  должна  быть  возложена  одна  единственная  обязанность.   • OCP  Принцип  открытости/закрытости. Программные  сущности  должны  быть  открыты  для  расширения,  но  закрыты  для  изменения.   • LSP  Принцип  подстановки  Барбары  Лисков. Объекты  в  программе  могут  быть  заменены  их  наследниками  без  изменения  свойств   программы.   • ISP  Принцип  разделения  интерфейса. Много  специализированных  интерфейсов  лучше,  чем  один  универсальный.   • DIP  Принцип  инверсии  зависимостей. Зависимости  внутри  системы  строятся  на  основе  абстракций.  Модули  верхнего  уровня  не   зависят  от  модулей  нижнего  уровня.  Абстракции  не  должны  зависеть  от  деталей.  Детали   должны  зависеть  от  абстракций.  
  • 23. SRP:  Single  Responsibility  Principle   (принцип  единственной  обязанности) Не  должно  существовать  более  одного   мотива  для  изменения  данного  класса class  01  SRP  OFF Customer +   GetName():  const  char* Order Product +   CalculateTax():  double +   GetName():  const  char* +   GetPrice():  double +   MakeReservation():  bool class  01  SRP  ON Customer +   GetName():  const  char* Order Product +   GetName():  const  char* +   GetPrice():  double TaxCalculator +   CalculateTax(Product):  double ProductReservation +   ReserveProduct(Product):  bool *антипаттерн
  • 24. OCP:  Open/Closed  Principle  (принцип   открытия/закрытия) Объекты  проектирования  (классы,  функции,   модули  и  т.д.)  должны  быть  открыты  для   расширения,  но  закрыты  для  модификации. class  02  OCP  OFF Customer +   GetName():  const  char* Order Product +   GetName():  const  char* +   GetPrice():  double TaxCalculator +   CalculateTax(Product):  double ProductReservation +   ReserveProduct(Product):  bool Catalogue +   FindByName(const  char*):  Product class  02  OCP  ON Customer +   GetName():  const  char* Order Product +   GetName():  const  char* +   GetPrice():  double TaxCalculator +   CalculateTax(Product):  double ProductReservation +   ReserveProduct(Product):  boolCatalogue +   FindByName(IFindSpecification):  Product «interface» IFindSpecification +   isIt(Product):  bool FindByNameSpecification +   isIt(Product):  bool FindByGroupSpecification +   isIt(Product):  bool *антипаттерн
  • 25. LSP:  Liskov Substitution  Principle  (принцип  замещения   Лисков) пример  SOLID_LSP Функции,  которые  используют  ссылки  на  базовые  классы,  должны  иметь   возможность  использовать  объекты  производных  классов,  не  зная  об  этом class Rectangle { protected: int width; int height; public: Rectangle(int w, int h) : width(w), height(h) {}; virtual void SetWidth(int value) { width = value; } virtual void SetHeight(int value) { height = value; } virtual int GetSquare() { return width * height; } }; class Square : public Rectangle { public: Square(int w, int h) : Rectangle(w,w) {}; virtual void SetWidth(int value) { width = value; height = value; } virtual void SetHeight(int value) { width = value; height = value; } };
  • 26. LSP:  Нарушение  принципа  LSP  (class  diagram) антипаттерн class  03  LSP Rectangle #   height:  int #   width:  int +   GetSquare():  int +   Rectangle(int,  int) +   SetHeight(int):  void +   SetWidth(int):  void Square +   SetHeight(int):  void +   SetWidth(int):  void +   Square(int,  int)
  • 27. ISP:  Interface  Segregation  Principle  (принцип   изоляции  интерфейса) пример   SOLID_ISP Клиент  не  должен  вынужденно  зависеть  от  элементов  интерфейса,  которые  он  не   использует. Другими  словами  этот  принцип  можно  сформулировать  так:  зависимость  между  классами   должна  быть  ограничена  как  можно  более  узким  интерфейсом. class IBusinessMenu { protected: virtual const char* GetFirstItem() =0 ; virtual const char* GetSecondItem() =0; virtual const char* GetCompot() =0 ; public: void PrintMenu() { if (GetFirstItem() != nullptr) std::cout << "Item:" << GetFirstItem() << std::endl; if (GetSecondItem() != nullptr) std::cout << "Item:" << GetSecondItem() << std::endl; if (GetCompot() != nullptr) std::cout << "Item:" << GetCompot() << std::endl; } };
  • 28. ISP:  Class  Diagram антипаттерн class  04  ISP CoffeMenu -­   bulka:  std::string -­   coffe:  std::string +   CoffeMenu(std::string,  std::string) #   GetCompot():  char* #   GetFirstItem():  char* #   GetSecondItem():  char* BusinessMenu -­   compot:  std::string -­   first:  std::string -­   second:  std::string +   BusinessMenu(std::string,  std::string,  std::string) #   GetCompot():  char* #   GetFirstItem():  char* #   GetSecondItem():  char* IBusinessMenu #   GetCompot():  char* #   GetFirstItem():  char* #   GetSecondItem():  char* +   PrintMenu():  void
  • 29. ISP:  Sequence  Diagram антипаттерн sd  04  ISP BusinessMenu CoffeMenu main PrintMenu() PrintMenu()
  • 30. DIP:  Dependency  Inversion  Principle   (принцип  обращения  зависимости) пример SOLID_DIP Модули  верхних  уровней  не  должны  зависеть  от  модулей  нижних  уровней.  Оба  типа   модулей  должны  зависеть  от  абстракций.  Абстракции  не  должны  зависеть  от  деталей.   Детали  должны  зависеть  от  абстракций. class IItem { public: virtual void print() = 0; }; class Menu { private: std::vector<IItem*> items; public: void add(IItem *i) { items.insert(items.end(),i); } void menu() { for (auto i : items) i->print(); } };Стратегия  Menu  применяется  к   интерфейсу  IItem.  Этим  мы  устранили   недостатки  предыдущего  варианта.
  • 31. DIP:  Class  Diagram class  05  DIP ItemBulka +   print():  void IItem +   print():  void ItemCoffe +   print():  void Menu -­   items:  std::vector<IItem*> +   add(IItem*):  void +   menu():  void
  • 32. DIP:  Sequence  Diagram sd  05  DIP IItemMenu main ItemBulka ItemCoffe menu() add(IItem*) add(IItem*) *print()
  • 33. Tell  Don’t  Ask пример SOLID_TDA,  CQS Один  из  основополагающих  принципов  ООП:  Необходимо   делегировать  объекту  действия,  вместо  того,  что  запрашивать  его   детали  реализации.Это  помогает  достичь  многократного   использование  класса  (поскольку  ни  кто  не  знает  его  деталей   реализации). Command  Query  Separation  – принцип  разделение  методов,   которые  выполняют  какие-­‐либо  действия  (tell)  и  методов,   которые  осуществляют  запросы  данных  (ask). Law  of  Demeter  – объект  может  вызывать  методы  только: • Себя • Своих  параметров • Объектов,  созданных  внутри  метода
  • 34. Модифицируемость  vs  Performance Разделение  данных  на  домены  ведет  к  увеличению   распределенности  объектов  между  сервисами,  что  ухудшает   производительность. Разделение  системы  на  слои,  увеличивает  количество   преобразований  данных,  что  так  же  отрицательно  влияет  на   производительность. Использование  операций  в  терминах  домена  приводит  к   тому,  что  появляется  дополнительное  преобразование   данных  из  внутренней  модели  во  внешнюю.  Что  так  же   отрицательно  влияет  на  производительность. 34