четверг, 5 ноября 2015 г.

J.B. Rainsberger - Integrated Tests Are A Scam


Так же видео можно посмотреть здесь: https://vimeo.com/80533536

Когда падает интеграционный тест, мы не можем сказать где именно проблема. И это плохо. После падения теста мы должны как можно точнее знать место, где ошибка.

Unit tests плохое название, лучше отражает суть Isolated tests.

Интеграционные тесты, в отличие от юнит тестов, не влияют на дизайн программы и не позволяют выявить проблемы в нем.

По этому, чем больше интеграционных тестов, темболее вероятно, что с приложением проблемы.

Люди, которые предлагают вам решать проблемы добавлением интеграционных тестов, продают вам аспирин, который усиливает головную боль.

воскресенье, 20 сентября 2015 г.

Паттерны проектирования на платформе .NET

 Обзор книги: http://habrahabr.ru/post/260649/

Блог автора: http://sergeyteplyakov.blogspot.com/
















Введение

Чтобы использовать паттерн проектирования по максимуму, нужно вникнуть в его суть, понять, какую проблему он призван решить и каким образом он это делает.

Канонические примеры большинства паттернов, приведенные "бандой четырех", включают в себя наследование. Но это не значит, что вы должны слепо использовать его. Наследование должно применяться осознанно и лишь тогда, когда обеспечиваемая им гибкость деуствительно необходима.

Паттерн "Стратегия"

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


Паттерн "Шаблонный метод"

(Для обеспечения тестируемости) Вместо выделения интерфейса можно воспользоваться разновидностью паттерна "Шаблонный метод" под названием "Выделение и переопределение зависимости". Суть техники заключается в выделении изменчивого поведения в виртуальный метод, поведение которого затем можно переопределить в тесте.

В юнит-тестах практически невозможно учесть все тонкости, которые могут возникнуть. При работе с внешним окружением, помимо юнит-тестов, обязательно должны присутствовать интеграционные тесты, которые проверят граничные условия в сложных ситуациях.

Паттерн освобождения ресурсов (Dispose Pattern)

Почему вообще появилась необходимость управления ресурсами в системе с автоматической сборкой мусора? Потому что, помимо памяти, приложение может владеть и другими важными ресурсами, такими как дескрипторы файлов и потоков, мьютексы, семафоры и т.п. Время сборки мусора зависит от многих фактором и не может (и не должно) контролироваться приложением. С ресурсами дело обстоит иначе: разработчик должен приложить все усилия, чтобы время владения ими было минимальным...

Управление ресурсами в .NET основывается на интерфейсе IDisposable, метод Dispose которого вызывается пользовательским кодом, и на финализаторе (finalizers), который вызывается во время сборки мусора. Разница между финализатором и методом Dispose состоит в том, что первый вызывается сборщиком мусора в неизвестый момент времени.  Второй вызывается пользовательским кодом, после чего ссылка на "мертвый" объект продолжает существовать.

Паттерн "Посредник"

Классы чтения и сохранения логов являются независимыми шагами импорта лог-файлов и не должны знать друг о друге...

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

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

Слабую связанность нужно обеспечивать на границах модуля, а не внутри него.

Обобщение простого решения, в котором нет никакой необходимости, убило не один проект.

Значительно лучше начинать с явного решения и обобщать его лишь тогда, когда стало понятно, в чем заключается обобщение и что оно действительно нужно.

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

Любая критически важная логика должна быть подвержена тестам. Точка.

Ненужно разделать с помощью посредника тесно связанные вещи.

Паттерн "Итератор"

Для поддержки цикла foreach не обязательно наличие интерфейса IEnumerable/IEnumerable<T>. достаточно, чтобы класс коллекции содержал метод GetEnumerator, который будет возвращать тип с методом bool MoveNext() и свойством Current.

Футбольная команда не является спииском игроков, поэтому класс FootballTeam не должен наследовать List<Player>.

Принцип единственной обязанности

Гибкость всегда приводит к увеличению сложности.

Чем меньше у метода, класса или модуля вспомогательных задач, тем ниже вероятность случайных изменений.

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

Наличие или отсутствие нарушения SRP очень зависит от того, насколько сложным является каждый из описанных ране шагов. Метод будет нарушать SRP, если валидация аргументов занимает 40 строк кода и находится в разных его частях.

Но класс может и не нарушать SRP, если он читает и сохраняет данные, но на каждую операцию требуется две строки кода.

Принцип "открыт/закрыт"

Мы должны ограничить каскад изменений и свести их количество к минимуму.

Открытость дизайна не означает расширения функциональности совсем без внесения изменений. Гибкий (supple) дизайн позволяет изменять поведение путем внесения изменений в модули, ответственные за данное поведение. При этом изменения второстепенных модулей отсутствует либо их число сведено к минимуму.

Принцип единственного выбора: всякий раз, когда система программного обеспечения должна поддерживать множество альтернатив, их полный список должен быть известен только одному модулю системы.

Классический объектный подход позволяет легко добавлять новые типы в существующую иерархию типов, а функциональный подход позволяет легко добавлять новые операции.

Принцип подстановки Лисков

"Должна существовать возможность использовтаь объекты производного класса вместо объектов базового класса". Это значит, что объекты производного класса должны вести себя согласованно, согласно контракту базового класса."

Основной смысл любой иерархии наследования в том, что она позволяет использовать базовые классы полиморфным образом, не задумываясь о том, экземпляр какого конкретного класса был передан.

Именно наличие контракта позволяет четко понять, нарушает производный класс принцип подстановки Лисков или нет.

Принцип разделения интерфейсов

Добиться простоты использования кода можно за счет проектирования чистых интерфейсов - интерфейсов, предоставляющие цельный набор операций, которого будет необходимо и достаточно большинству клиентов.

Принцип инверсии зависимостей

"Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Абстракции не должны зависеть от деталей. Детали должны зависить от абстракций"

Наличие интерфейсов образует дополнительный уровень косвенности (или дополнительный уровень абстрации), что затрудняет понимание системы.

Не для всех классов нужно выделять интерфейсы, и не все зависимости следует требовать извне в виде интерфейсов.

Легко столкнуться с проблемой чрезмерно абстрактных решений, когда интерфейсов слишком много и решение настолько гибкое и слабосвязное, что просто невозможно понять, кто за что отвечает и откуда начать изучение.

Исходный смысл принципа инверсии зависимостей в том, чтобы классы нижнего уровня взаимодействовали с верхним уровнем косвенно, ничего о нем не зная.

Принцип инверсии зависимостей не сводится лишь к выделению интерфейсов и передаче их через конструктор. DIP объясняет, для чего это нужно делать.

Чтобы на завязываться на класс верхнего уровня, класс может объявить некоторый интерфейс и потребовать его экземляр через аргумент конструктора.

Зависимост класса должны располагаться на текущем или более высоком уровне абстракции.

Принцип инверсии зависсимостей (DIP) - это принцип проектирования, который говорит, что классы должны зависеть от высокоуровневых абстракций.

понедельник, 19 ноября 2012 г.

XPDays2012: UnExperience Report

Author: Paul Lipinsky

Agile doesn't solve problems. It helps us to solve problems.

Team should organize work as it wish.

It can be useful to change project for every team player once a two weeks if he wants.

Trust but check if customer is satisfied.

% of secure (quality) can be discussed.

Collaborative interview - the team interview applicant. This is not only technical interview, team select person with whom people will spend a lot of time.

Pair programming is very useful especially at the beginning. It very useful to have different points of view. Quality is growing and code becomes more stable.

You will start to write good code only after reading a lot of foreign code.

TDD ping pong: 1 create test, 2 create code, 1 refactor code: 4-eyes principle.

Programmer man

Don't be afraid to make mistakes but make conclusions from them.



XPDays2012: Путь XP практика: как стать и оставаться профессионалом

Профессионал - тот, кому нравится его работа и его работа нравится окружающим

У профессионала нет компромисов с качеством.

"Мы - эджальные пацаны. Оно будет готово тогда, когда оно будет готово"

Профессионал всегда открыт, его работа прозрачна.

Он умеет говорить НЕТ.

Овертаймы уменьшают эффективность.

Профессионал не ищет виновных.

UML - средство коммуникации, а не документации.

Онлайн-курсы: Coursera, Udacity

TDD-kata

Фильм Карате-Кид

Правило 72 часов: если ты что-то узнал и не применил в течение 72 часов, ты это забудешь.




XPDays2012: TDD in the real world

Author: Johannes Brodwall

No more architecture than it's needed

Web-server Jetty

Copy-Past pattern

Keep application simple, avoid "magic"

Don't use framework if you cannot write it by yourself 

воскресенье, 18 марта 2012 г.

Александр Якима. Тренинг "Канбан для проектов поддержки ПО"

Небольшое усилие помогает сильно, большое усилие помогает слабо

Стивен Макконнелл. Совершенный код


"Обращайте внимание на признаки того, что программу неудобно понять. Об этом свидетельствуют любые неудобства.
Если вы разгадываете код, а не читаете его, он слишком сложен.
Если он сложен - он неверен. Сделайте его проще!"