XP практики в проектах с тяжелой наследственностью

Preview:

DESCRIPTION

Олег Клименко, разработчик, компания Sigma Ukraine

Citation preview

XP практики в проектахс тяжелой наследственностью

Oleg KlymenkoJava Developer @ Sigma Ukraine oklym@meta.ua

Начало

Развитие

Agile-манифест разработки программного обеспечения

Мы постоянно открываем для себя более совершенные методы разработки программного обеспечения, занимаясь разработкой

непосредственно и помогая в этом другим.Благодаря проделанной работе мы смогли осознать, что:

Люди и взаимодействие важнее процессов и инструментовРаботающий продукт важнее исчерпывающей документации

Сотрудничество с заказчиком важнее согласования контрактаГотовность к изменениям важнее следования первоначальному плану

То есть, не отрицая важности того, что справа,мы всё таки больше ценим то, что слева.

Идея

Процесс

Ожидание

Реальность

Демотивация

Первый шаг

1. Страсть (избыток проектирования)2. Чревоугодие (неспособность к рефакторингу)3. Жадность (соревнование между командами разработки)4. Лень (отсутствие проверки входных данных)5. Гнев (отсутствие практики комментировать код)6. Зависть (не использование систем управления версиями)7. Гордость (отсутствие юнит-тестирования)

Neil McAllister8. Оптимизм9. 10.

Анализ

Новая фича

Новая фича

Тест разработчика

DT

$

Вызов

1. Я пишу пользовательский интерфес2. Трудно сопровождать3. Они не ловят новые “баги”4. Они медленные5. Это скучно6. Это дело тест-тима7. У меня легаси код8. Мне нужно делать фичи9.

Отговорки

public class Validator {private static Validator instance =

new Validator(FeatureFactory.get());private Subscription subscr;private final Player player;

public static Validator getInstance() {return instance;}

private Validator(FeatureFactory ff) {player = ff.getPlayer();if (player instanceof GamePlayer)

subscr = ff.findSubscription(player);}

public boolean check(Round round) {SyncService sync = Repository.lookup(SyncService.class);boolean result = false;Date time = new Date();if(!round.isActiveInTime(time)) {

try {sync.lock(round);Ticket ticket = new SubscriptionTicket(subscr);result = round.subscribe(ticket, player);

}finally {

sync.unlock(round);}

}return result;

}}

public class Validator {private static Validator instance =

new Validator(FeatureFactory.get());private Subscription subscr;private final Player player;

public static Validator getInstance() {return instance;}

private Validator(FeatureFactory ff) {player = ff.getPlayer();if (player instanceof GamePlayer)

subscr = ff.findSubscription(player);}

public boolean check(Round round) {SyncService sync = Repository.lookup(SyncService.class);boolean result = false;Date time = new Date();if(!round.isActiveInTime(time)) {

try {sync.lock(round);Ticket ticket = new SubscriptionTicket(subscr);result = round.subscribe(ticket, player);

}finally {

sync.unlock(round);}

}return result;

}}

public class V {private static V instance =

new V(FF.get());private S s;private final P p;

public static V getInstance() {return instance;}

private V(FF ff) {p = ff.getP();if (player instanceof GamePlayer)

s = ff.findS(player);}

public boolean do(R r) {SS sync = Repository.lookup(SS.class);boolean result = false;Date time = new Date();if(!round.timeDependentRoutine(time)) {

try {sync.lock(round);T t = new ST(s);result = round.s(t, player);

}finally {

sync.unlock(round);}

}return result;

}}

public class Validator {private final Subscription subscr;private final Player player;private final SyncService sync;

public Validator(Player player, Subscription subscr, SyncService sync) {

this.player = player;this.subscr = subscr;this.sync = sync;

}

public boolean check(Round round, Date time) {boolean result = false;if(!round.isActiveInTime(time)) {

try {sync.lock(round);Ticket ticket = new SubscriptionTicket(subscr);result = round.subscribe(ticket, player);

}finally {

sync.unlock(round);}

}return result;

}}

1. Смешивание инстанциирования с логикой2. Смешивание патерна Lookup с логикой3. Выполнение целевой логики в конструкторе4. Глобальная видимость полей класса5. Использование патерна Singleton6. Статические методы7. Глубокая иерархия наследования8. Смешивание сервисов с общей логикой

Антипатерн

Тестируемость

1. Сбалансированный ООП дизайн.2. Внедрение внешних зависимостей (DI).3. Отслеживание ошибок смешивания логики.4. Соблюдение закона Деметры.5. Юнит тесты (TDD).

Норма

Unit тесты

Функциональные и интеграционные тесты

Системные тесты

Переворот

Время

Человеческий фактор

Исходный код

Исходный код

Архитектура и ДизайнАрхитектура и Дизайн

КомментарииКомментарии

СтандартыкодированияСтандарты

кодирования

Потенциальныеошибки

Потенциальныеошибки

Дублированиекода

Дублированиекода

Юнит тестыЮнит тесты

СложностьСложность

Контроль

Итоговый план

1. Налаживаем сборку/инсталяцию.2. Определяем поведенческие требования.3. Создаем покрытие функциональными тестами.4. Выполняем рефакторинг.5. Покрываем юнит тестами.6. Налаживаем инспекцию кода.7. Убираем излишние функциональные тесты.8. Оставляем мир лучше чем был до нас :)

Пять минут...

1. Miško Hevery. Writing Testable Code http://misko.hevery.com/code-reviewers-guide/

2. Wiktor Żołnowski. Reversed Tests Pyramid http://xpdays.com.ua/materials/legacy-code/

3. Neil McAllister. 7 deadly sins of software development http://gigaom.com/2012/06/02/the-7-deadly-sins-of-software-development/

Recommended