Upload
serhiy-kalinets
View
1.976
Download
4
Embed Size (px)
DESCRIPTION
Мой доклад с XP Days Ukraine 2011
Citation preview
SOLIDный код: с TDD это просто
Сергей Калинец http://tdd4.netSkype: sergiikalinets
@skalinets
Обо мне
• Более 10 лет в промышленной разработке• Руковожу разработкой в киевском офисе
компании CompatibL• Тренер по инженерным практикам в
scrumguides.com• Ведущий клуба практической разработки в
stratoplan.ru
Disclaimer
Надиктовано КО
История одного проекта
TDD: добро
• Уверенность в коде до запуска• Нет лишнего кода• Быстрее принимаются решения
TDD: зло
• Замедление рефакторинга
• Сложные тесты• Каскадные
отказы тестов
Жизнь проекта
• Черное-белое-черное-белое, а потом -- …
Как победить зло?
Уровни качества
Плохой дизайн это…
Неоправданная сложность
В системе есть инфраструктура, которая или не используется, или используется
неправильно
Повторение
Дубликаты структур, которые должны иметь общую
абстракцию.
Мутность
Код сложно понимать
Жесткость
Систему сложно изменять.
Монолитность
Сложно выделить компоненты, которые можно использовать повторно
Вязкость
Делать что-то правильно сложнее, чем делать это неправильно.
ХрупкостьИзменения легко ломают систему и приводят к новым
изменениям.
Решение
• Single Responsibility
• Open/Closed
• Liskov Substitution
• Interface Segregation
• Dependency Inversion
Single Responsibility
У класса есть только одна ответственность, он умеет ее делать и делает ее хорошо
Single Responsibility
from http://microsoftnlayerapp.codeplex.com/
Single Responsibility: Test
• Данные– Что знает?– Какие связи
между объектами поддерживает?
• Поведение– Что решает?– Какие услуги
предоставляет?
Single Responsibility
Show me the code: MessageHandler
Open/Closed• Программные сущности (классы, модули,
методы и т.д.) должны быть открыты для расширения, но закрыты от изменений
Было
Стало
Open/Closed и TDD
• Нет каскадных отказов тестов
• Не нужно менять работающий код
• Про тесты я уже говорил?
Open/Closed
Show me the code: OrderCalculator
Liskov Substitution
Клиенты, использующие базовый класс, должны работать и с его наследниками, не зная этого.
Liskov Substitution
• Предусловия не могут быть ужесточены в наследнике
• Постусловия не могут быть ослаблены в наследнике
• Инварианты базового типа должны соблюдаться и в наследнике
• Исторические ограничения
Liskov Substitution и TDD
• Тесты могут проверять использование наследников вместо предков
• В случае нарушения юнит тесты усложняются
Liskov Substitution
Show me the code: ReadOnlyQueue
Interface Segregation
• Utility Modules should be included полностью
• Тесты на страже Extract interface/base class• Тестовые дублёры могут скрывать
нарушения
Interface Segregation
Клиентам не должны навязываться интерфейсы, которые им не нужны.
Interface Segregation и TDD
• Тестовые дублеры диктуют API
• Тесты усложняются, когда зацепление понижается
• Тесты обезбаливают разбиение интерфейсов
Dependency Inversion
• Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций.
• Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Dependency Inversion и TDD
• Service Locator или Dependency Injection?
• Двойники в TDD создают абстракции
• Настройка тестов легче с Dependency Injection
Dependency Inversion
Show me the code
Начать никогда не поздно!
• Extract interface/superclass
• Use base type where possible
• Extract parameter
SOLID & YAGNI & KISS
Yo Aren’t Gonna Need It
Keep It Simple Stupid
Выводы
• SOLID упрощает TDD
• TDD упрощает SOLID
• Вместе они упрощают нашу жизнь