Software Design Общие практики Бреслав А. А. Основные проблемы Сложность задачи Сильные зависимости между частями системы Трудно рассматривать одну часть системы отдельно от других Дублирование (не только.
Download ReportTranscript Software Design Общие практики Бреслав А. А. Основные проблемы Сложность задачи Сильные зависимости между частями системы Трудно рассматривать одну часть системы отдельно от других Дублирование (не только.
Бреслав А. А.
Software Design
Общие практики
Основные проблемы
Сложность задачи Решение не умещается в голове целиком Сильные зависимости между частями системы Трудно рассматривать одну часть системы отдельно от других Дублирование (не только кода, но и структуры, идей и т.д.) Одно и то же реализовано в нескольких местах. Возможно, по-разному.
Запутанность Трудно разобраться в том, что уже создано Одна из причин - дублирование Паттерны проектирования. Введение Бреслав А. А.
Принципы решения (1)
Сложность задачи Декомпозиция (разбиение на более мелкие подзадачи) Модульность (каждый модуль решает свою четко поставленную задачу) Сильные зависимости между частями системы Инкапсуляция – зависимости только от интерфейса Логичное разбиение на замкнутые модули Дублирование (не только кода, но и структуры, идей и т.д.) Повторное использование Использование стандартной библиотеки Улучшение дизайна, если повторное использование затруднено Бреслав А. А.
Паттерны проектирования. Введение
Принципы решения (2)
Запутанность Модули не смешивают ответственности Устранение дублирования Единство дизайна Самодокументирующийся код Метафоры Конвенции кодирования Использование идиом языка Отсутствие ненужной оптимизации Отсутствие ненужных обобщений Документация Паттерны проектирования. Введение Бреслав А. А.
Общий принцип
Красота спасет мир от засилья интеллекта
Если все написано красиво (просто, понятно и удобно), все будет хорошо.
Бреслав А. А.
Паттерны проектирования. Введение
Важная рекомендация
Не ленитесь думать Ленитесь писать код
Думайте о логичной декомпозиции устранении дублирования Опасайтесь дырявых абстракций например, вызов виртуального метода в конструкторе слишком трудоемкого обобщения преждевременной оптимизации преждевременной пессимизации Паттерны проектирования. Введение Бреслав А. А.
Пессимизация
Использование медленных алгоритмов, когда более быстрые реализуются ничуть не сложнее конкатенация строк в цикле использование synchronized без необходимости прямой доступ к элементам LinkedList Паттерны проектирования. Введение Бреслав А. А.
Закон дырявых абстракций
ЛЮБАЯ НЕТРИВИАЛЬНАЯ АБСТРАКЦИЯ В КАКОЙ-ТО МЕРЕ ЯВЛЯЕТСЯ ДЫРЯВОЙ.
ВСЕГДА НАДО ДУМАТЬ О ТОМ, КАК РЕАЛИЗОВАНА ТА ИЛИ ИНАЯ АБСТРАКЦИЯ. Паттерны проектирования. Введение Бреслав А. А.
Еще одна проблема
Изменяющиеся требования Заказчик никогда не может точно сказать, что именно ему нужно С новыми версиями добавляется новая функциональность, о которой не было известно во время работы над предыдущими версиями Паттерны проектирования. Введение Бреслав А. А.
Расширяемость
Что нам поможет Инкапсуляция – можно заменить простую реализацию более сложной, не меняя клиентов Модульность – точно известно, кто за что отвечает, и куда что добавить Логичная структура классов Паттерны проектирования. Введение Бреслав А. А.
Иерархии классов
Каждый класс должен описывать определенное понятие (модульность) не больше, не меньше Подклассы должны
уточнять
определено суперклассом то, что Наследование – отношение частного случая: подкласс – частный случай суперкласса При других отношениях между понятиями наследование применять нельзя Паттерны проектирования. Введение Бреслав А. А.
Повторное использование
Наследование – мощный инструмент повторного использования Но, если один класс не является частным случаем другого, а лишь использует все его умения, лучше использовать
агрегацию
хранить объект используемого класса внутри объекта использующего класса Паттерны проектирования. Введение Бреслав А. А.
Инкапсуляция
Необходимо максимально инкапсулировать реализацию прятать ВСЕ поля, по возможности даже от наследников использовать максимально абстрактные ссылки предоставлять минимальный API Паттерны проектирования. Введение Бреслав А. А.
Бреслав А. А.
Software Design
Хороший код
Не устану повторять…
Избегать дублирования Избегать ненужных обобщений Избегать ненужной оптимизации Избегать ненужной пессимизации Инкапсулировать все, что можно Опасаться дырявых абстракций Паттерны проектирования. Введение Бреслав А. А.
Внесение изменений в код
Каждая модификация кода потенциально вносит ошибку Важно минимизировать количество изменений, необходимых для добавления/исправления чего бы то ни было Ошибки должны появляться там, где мы вносили изменения, а не где-то еще Паттерны проектирования. Введение Бреслав А. А.
Как минимизировать изменения
Логичное разбиение задачи на модули если для того, чтобы что-то сделать, нужно изменить что-то в трех местах, то, возможно, эти три места являют собой один модуль Инкапсуляция Если при изменении реализации не меняется API, нам не придется менять код клиентов Паттерны проектирования. Введение Бреслав А. А.
Практики кодирования
Объявлять переменные только в тот момент, когда они становятся нужны и сразу инициализировать Не заводить лишних полей поле – это почти глобальная переменная Использовать именованные константы повторение литералов в коде – дублирование поди найди, где нужно изменить, если значение изменилось Паттерны проектирования. Введение Бреслав А. А.
Максимально абстрактные ссылки
Если нужен просто список – напишите List Это дает возможность, не изменяя клиентского кода, заменить одну реализацию списка другой – в инициализации переменной.
Если нужен динамический массив – напишите ArrayList.
Не вводите клиентов в заблуждение Здесь нельзя безболезненно заменить реализацию Паттерны проектирования. Введение Бреслав А. А.
Опасная перегрузка
class
Thing
{
public boolean
equals(Object other) {
return super
.equals(other); } } Добавим еще метод:
public boolean
equals( Thing other) {
return this
.field == other.field; } Что плохого?
Паттерны проектирования. Введение Бреслав А. А.
Как избегать проблем при перегрузке
Не определять несколько перегруженных методов с одинаковым числом параметров Вообще не злоупотреблять перегрузкой Бреслав А. А.
Паттерны проектирования. Введение
Зависимости между методами
Если методы обмениваются информацией через поля, это может вести к ошибкам Методы должны по возможности общаться через параметры и возвращаемые значения Лучший метод – метод без побочных эффектов Паттерны проектирования. Введение Бреслав А. А.
Когда использовать поля
Поле – это элемент
состояния объекта
Понятие, реализуемое классом, характеризуется некоторым
атрибутом
По возможности значение атрибутов (полей) не должно влиять на поведение объекта Паттерны проектирования. Введение Бреслав А. А.
Другие проблемы с полями
Недостаточная инициализация После создания объекта, он еще не готов к использованию, потому что некоторые поля не проинициализированы Например, для завершения инициализации нужно вызвать специальный метод Клиент никогда до этого не додумается Конструктор должен создавать полностью пригодный к использованию объект Паттерны проектирования. Введение Бреслав А. А.
Неизменяемость
Нужно использовать final для полей, когда только возможно гарантируется полная инициализация можно кешировать вычисляемые значения методы не имеют побочных эффектов Все классы данных по возможности должны быть полностью неизменяемыми Паттерны проектирования. Введение Бреслав А. А.
Когда класс неизменяем
Все поля
final
Не хранятся ссылки на объекты, полученные извне Наружу не возвращаются ссылки на значения полей Полезно использовать
new
ArrayList(Collection c) array.clone() Collections.unmodifiableCollection() Паттерны проектирования. Введение Бреслав А. А.
Проблема нулевого флага
По возможности метод не должен возвращать
null
Неожиданные NPE далеко от источника ошибки Нет информации об ошибке Варианты Бросить исключение Вернуть Null Object Паттерны проектирования. Введение Бреслав А. А.
Null Object
Объект, означающий «отсутствие объекта» поддерживает интерфейс абстракции методы не делают ничего или кидают исключения Позволяет клиенту не обрабатывать ошибку вообще Лист в дереве Маркер конца списка Паттерны проектирования. Введение Бреслав А. А.
Источники
Макконнелл С., Совершенный код. Мастер-класс / Пер. с англ. – М.: Издательско-торговый дом «Русская редакция»; СПб.: Питер, 2005. – 896 стр.: ил.
Кент Бек, Экстремальное программирование. – СПб.: Питер, 2002 –224 с.: ил.
Эрик Аллен, Типичные ошибки проектирования. Библиотека программиста – СПб.: Питер, 2003. – 224 с.: ил.
Джоэл Спольски, Джоэл о программировании… – СПб: Символ-Плюс, 2006 – 352 с., ил.
Джошуа Блох, Java™. Эффективное программирование / Пер. с англ. – М.: Лори, 2002 Паттерны проектирования. Введение Бреслав А. А.
Задание
Описать интерфейс двоичного дерева поиска (из произвольных элементов с естественным порядком) создание пустого дерева создание дерева из массива (списка) элементов добавление проверка наличия элемента поиск минимума/максимума количество вершин проверка на пустоту Создать две реализации: Хранение элементов в динамическом массиве Каждая вершина – отдельный объект Паттерны проектирования. Введение Бреслав А. А.
Вопросы
Бреслав А. А.
Паттерны проектирования. Введение