Принципы и шаблоны проектирования GRASP / SOLID
(ЧАСТЬ 2)
Романенко Константин
Тетерятников Алексей
GRASP: general responsibility assignment software patterns
общие шаблоны распределения ответственностей
Шаблоны GRASP: план доклада
- Что такое шаблон проектирования ?
- Шаблоны-принципы и связь с SOLID
- Шаблоны-роли
Что такое шаблон проектирования ?
Характерная задача проектирования [классов] и эффективный способ ее решения.
Имя - Задача - Решение - Результаты
Буддистский шаблон решения проблем
У вас есть проблема ?
Да
Нет
Тогда не волнуйтесь!
Можете ли вы ее решить?
Нет
Да
Действуйте!
классификация шаблонов GRASP
Основные шаблоны
- Information expert (Информационный эксперт)
- Creator (создатель)
- High Cohesion (Высокая cцепленность)
- Low Coupling (Низкое связывание)
- Controller (Контроллер)
Дополнительные шаблоны
- Protected Variations (Устойчивость к изменениям)
- Polymorphism (Полиморфизм)
- Indirection (Перенаправление)
- Pure Fabrication (чистая выдумка, синтетика)
High Cohesion & Low Coupling
принципы: high cohesion / low coupling
Cohesion - Сцепленность
the act or state of sticking together tightly
Coupling - Связывание
the act of bringing ... together
"... система должна состоять из слабо связанных классов, которые должны содержать связанную бизнес — логику."
Низкое связывание
Low Coupling
принцип GRASP: low coupling
Для конкретного класса: как добиться возможности повторного использования и незначительного влияния изменений ?
Минимизировать количество данных о других элементах!
Пример нарушения: циклическая зависимость
принцип GRASP: low coupling
A
B
public class A {
private B b;
public A() {
this.b = new B(this);
}
}
public class B {
private A a;
public B(A a) {
this.a = a;
}
}
принцип GRASP: low coupling
Как обнулить связывание: атрибуты
- Удалить атрибуты нестандартных типов
Катавасия
кличка: String
ночноеЗрение: NightVision
принцип GRASP: low coupling
- Удалить атрибуты нестандартных типов
- Не вызывать службы классов другого типа
- Для параметров, возвращаемых значений и локальных переменных избавиться от нестандартных типов
Катавасия
void питаться()
void спать()
Мышь найтиМышь()
...
Как обнулить связывание: методы
принцип GRASP: low coupling
Катавасия
void питаться()
void спать()
...
Как обнулить связывание: полиморфизм
- Удалить атрибуты нестандартных типов
- Не вызывать службы классов другого типа
- Для параметров, возвращаемых значений и локальных переменных избавиться от нестандартных типов
- Отказаться от наследования и реализации интерфейсов
Нулевое связывание... А как же ООП?
принцип GRASP: low coupling
Высокая сцепленность
High Cohesion
принцип GRASP: high cohesion
Как обеспечить сфокусированность ответственности класса, управляемость и ясность?
Класс должны содержать сцепленную бизнес — логику!
Пример нарушения
принцип GRASP: high cohesion
Data
- temperature: int
- time: int;
...
- calcTemperature(): int
- calcTime(): int;
Пример реализации
принцип GRASP: high cohesion
TemperatureData
- temperature: int
...
- calcTemperature(): int
TimeData
- time: int
...
- calcTime(): int
принцип GRASP: high cohesion
Сцепленный класс
Менее сцепленный класс
приватное свойство или метод
публичное свойство или метод
принципы GRASP: high cohesion / low coupling
Максимизируйте сфокусированность
Минимизируйте зависимости
приватное свойство или метод
публичное свойство или метод
Связь с принципами SOLID
принципы GRASP и SOLID
High Cohesion
GRASP
SOLID
Высокая сцепленность
Единственная ответственность
Single Responsibility
Низкое связывание
Разделение интерфейсов
Low Coupling
Interface Segregation
принцип GRASP: protected variations
Устойчивость к изменениям
Protected Variations
Как спроектировать систему классов, чтобы изменение в одном классе не оказывало нежелательного влияния на другие классы?
Распределите ответственности, чтобы обеспечить устойчивый интерфейс!
принцип GRASP: protected variations
Точки вариации и точки эволюции
Точка эволюции - предполагаемая точка ветвления, которая может возникнуть в будущем
Точка вариации - точка ветвления в существующей на данный момент системе
принцип GRASP: polymorphism
Полиморфизм
Как обрабатывать альтернативные варианты поведения на основе типа?
Для однотипных классов используйте полиморфные операции!
принципы protected variations & polymorhpism
Пример реализации
class PasswordReminder {
// соединение с абстрактной СУБД
private DBConnectionInterface dbConnection;
PasswordReminder(DBConnectionInterface dbConnection) {
this.dbConnection = dbConnection;
}
}
Связь с принципами SOLID
принципы GRASP и SOLID
Dependency inversion principle
SOLID
GRASP
Устойчивость к изменениям
Protected Variations
Открытость/закрытость
Open/closed principle
Инверсия зависимостей
Полиморфизм
Принцип подстановки Барбары Лисков
классификация шаблонов в докладе
- Information expert (Эксперт)
- Creator (Создатель)
- Controller (Контроллер)
Шаблоны - роли
- Indirection (Перенаправление)
- Pure Fabrication (чистая выдумка, синтетика)
RDD: responsibility driven design
Проектирование на основе ответственностей
шаблон-роль GRASP: information expert
Информационный эксперт
Каков базовый принцип распределения ответственностей ?
Информация должна обрабатываться там, где она содержится!
Эксперт: пример
шаблон-роль GRASP: information expert
Эксперт: пример нарушения
шаблон-роль GRASP: information expert
AreaCalculator
public double sum() {
foreach(shape : this.shapes) {
if(is_a(shape, 'Square')) {
area.append( pow(shape.length, 2) );
} else if(is_a(shape, 'Circle')) {
area.append( pi() * pow(shape->radius, 2) );
}
}
return array_sum(area);
}
Эксперт: пример реализации
шаблон-роль GRASP: information expert
interface ShapeInterface {
public double area();
}
class Circle implements ShapeInterface {
public double area() {
return pi() * pow(shape->radius, 2)
}
}
шаблон-роль GRASP: information expert
Эксперт: пример реализации
Создатель
Какой класс должен отвечать за создание нового экземпляра некоторого класса?
Смотрим дальше!
шаблон-роль GRASP: creator
Создатель
- Содержит или агрегирует объекты целевого класса
- Активно использует
- Обладает данными инициализации
Например, при разработке набора настольных игр, объект класса Board включает в себя 0..n
объектов класса Square
шаблон-роль GRASP: creator
шаблон-роль GRASP: creator
Создатель: пример реализации
Контроллер
Какой класс должен отвечать координацию выполнения системных операций, поступающих
на уровне UI?
Отдельный класс Controller!
шаблон-роль GRASP: controller
шаблон-роль GRASP:controller
Пример реализации: REST-Контроллер
роль в GRASP: indirection
Перенаправление
Как перераспределить обязанности, чтобы избавиться от прямого связывания классов?
Присвойте обязанности промежуточному объекту, который перенаправляет связи!
Используйте интерфейс!
РассчитатьНалог(позиция)
<<Интерфейс АдаптерРасчетаНалога>>
шаблон-роль GRASP: indirection
Перенаправление: пример
РассчитатьНалог(позиция)
<<АдаптерСистемы1>>
РассчитатьНалог(позиция)
<<АдаптерСистемы2>>
шаблон-роль GRASP: indirection
Перенаправление: пример
ГлавныйНалоговыйАдаптер
...
Продажа
ПолучитьВеличинуНалогов(Продажа)
РассчитатьНалог(позиция)
sum =итого()
роль в GRASP: pure fabrication
Чистая выдумка (синтетика)
Какой класс должен обеспечить реализацию high cohesion/low coupling, если шаблон expert не подходит ?
Присвойте обязанности искусственному классу, не представляющему конкретного понятия предметной области!
Итоги GRASP
- Предпочтение "простым" классам, экспертам своей ответственности
- При усложнении определенная функциональность или связь с другими классами выносится в отдельную структуру
- Точки изменения защищаются с помощью абстрактных (полиморфных) операций (необходимо оценивать вероятность возможных модификаций)
- Для конкретной решения задачи можно "синтезировать" класс, отсутствующий в предметной области (например, Контроллер)
Общие итоги SOLID и GRASP
Общие итоги SOLID и GRASP
Цель программной инженерии - построения ПО высокого качества.
Внешние факторы понятны пользователям (корректность, простота использования, эффективность, своевременность и др.)
Для разработчика так же важны внутренние факторы качества, которые делают ПО простым для понимания, модификации, документирования, поддержки и рефакторинга.
Библиография
1. Крэг Ларман. Применение UML 2.0 и шаблонов проектирования (ozon.ru)
3. GRASP на youtube
3-b Сергей Немчинский
https://www.youtube.com/watch?v=jw3f8OrjYT0
https://www.youtube.com/watch?v=UxXsCS6fbJ0
2. GRASP на Хабр
1. Крэг Ларман. Применение UML 2.0 и шаблонов проектирования (ozon.ru)
GRASP
By kromanenko-sis
GRASP
- 191