Про "квадраты" и "стрелки" я немного поразглагольствовал вот тут - http://programmingmindstream.blogspot.ru/2014/01/uml.html
Теперь хочется немного "полить воду" про мою ЛЮБИМУЮ тему - "разработка через тестирование".
Или "разработка на костылях тестов" :-) что - ВЕРНЕЕ.
Ну во-первых "хорошая тестируемость классов ведёт к хорошей их архитектуре".
Про это писал Тепляков:
http://programmingmindstream.blogspot.ru/2014/01/blog-post_3560.html
http://programmingmindstream.blogspot.ru/2014/01/blog-post_626.html
И ещё один автор:
http://18delphi.blogspot.ru/2013/11/blog-post_1441.html
Приведённые выше авторы озвучили ОДНУ "банальную" мысль, о которой я ДОЛГО думал, но никак не смог озвучить САМ.
А именно:
"Лакмусовая бумажка архитектурного решения
Повторю ЕЩЁ раз. Как Я САМ это понимаю - "хорошо спроектированный класс - хорошо тестируется и НАОБОРОТ хорошо тестируемый класс - ХОРОШО спроектирован".
Ну ТАК я ДЛЯ СЕБЯ это ТЕПЕРЬ понимаю.
Примеров "из жизни" - у меня есть масса. Поверьте мне на слово :-) Для "особо интересующихся" - я могу попробовать собрать "дайджест".
Кстати слово "класс", тут не стоит воспринимать БУКВАЛЬНО. За ним может "маскироваться" и реальный проектный класс, и библиотека, и подсистема и проект.
Но это не всё что я хотел сказать.
Хочу сказать ещё одну "банальную" мысль. Уже НЕ РАЗ повторенную "классиками", но я ПРОЧУВСТВОВАЛ её на СЕБЕ.
Тесты это НЕ ТОЛЬКО (да и не столько) способ "поверки" правильности кода и его соответствия ТЗ.
Тесты это ещё и "пример использования" проектных классов и архитектурных решений.
У меня есть много кода, который покрыт тестами, но "написан давно" и НЕ ВМЕЩАЕТСЯ ни в хранилище "графических образов", ни в хранилище "строк кода" в моём мозгу.
Но! ПОСКОЛЬКУ этот код ХОРОШО и плотно покрыт тестами - мне и НЕ НАДО "его помнить".
Я ВСЕГДА могу посмотреть на ТЕСТЫ и понять - "как это работает" и "зачем это нужно".
ВСЁ! Мне НЕ НАДО "помнить код" и его детали.
Мне ДОСТАТОЧНО взят тесты и "перезагрузить" мой "кеш мозга".
ОЧЕНЬ УДОБНО. Для МЕНЯ ЛИЧНО.
Если кому-то этот подход - ИНТЕРЕСЕН - обращайтесь - могу попробовать и вас "прозомбировать".
P.S. А тут за рамками "выступления" осталось "аспектно-ориентированное программирование".
P.P.S. в том же самом проекте, где "нет UML" - нет и "нормальных тестов". И отчасти поэтому - он "тяжело программируется". Хотя и в РАЗЫ меньше других проектов.
Теперь хочется немного "полить воду" про мою ЛЮБИМУЮ тему - "разработка через тестирование".
Или "разработка на костылях тестов" :-) что - ВЕРНЕЕ.
Ну во-первых "хорошая тестируемость классов ведёт к хорошей их архитектуре".
Про это писал Тепляков:
http://programmingmindstream.blogspot.ru/2014/01/blog-post_3560.html
http://programmingmindstream.blogspot.ru/2014/01/blog-post_626.html
И ещё один автор:
http://18delphi.blogspot.ru/2013/11/blog-post_1441.html
Приведённые выше авторы озвучили ОДНУ "банальную" мысль, о которой я ДОЛГО думал, но никак не смог озвучить САМ.
А именно:
"Лакмусовая бумажка архитектурного решения
Я неоднократно писал о лакмусовой бумажке хорошего дизайна. Когда я рассматриваю дизайн класса или модуля, то стараюсь понять насколько он является цельным и слабосвязным (все те же low coupling и high cohesion) с помощью юнит-тестов. Если их написать невозможно или они будут невменяемыми, то это говорит мне, что с дизайном что-то не то.
А как определить качество архитектурного решения? Чтобы понять, как далеко некоторое решение проникло (или проникнет) в разные части системы, я задаю себе такой вопрос: «А что если я ошибся и мне придется изменить это решение в будущем? Какие будут последствия?». Если некоторое решение размазано ровным слоем по всему приложению, то стоимость его изменения будет огромной, а значит это решение является архитектурным."
Повторю ЕЩЁ раз. Как Я САМ это понимаю - "хорошо спроектированный класс - хорошо тестируется и НАОБОРОТ хорошо тестируемый класс - ХОРОШО спроектирован".
Ну ТАК я ДЛЯ СЕБЯ это ТЕПЕРЬ понимаю.
Примеров "из жизни" - у меня есть масса. Поверьте мне на слово :-) Для "особо интересующихся" - я могу попробовать собрать "дайджест".
Кстати слово "класс", тут не стоит воспринимать БУКВАЛЬНО. За ним может "маскироваться" и реальный проектный класс, и библиотека, и подсистема и проект.
Но это не всё что я хотел сказать.
Хочу сказать ещё одну "банальную" мысль. Уже НЕ РАЗ повторенную "классиками", но я ПРОЧУВСТВОВАЛ её на СЕБЕ.
Тесты это НЕ ТОЛЬКО (да и не столько) способ "поверки" правильности кода и его соответствия ТЗ.
Тесты это ещё и "пример использования" проектных классов и архитектурных решений.
У меня есть много кода, который покрыт тестами, но "написан давно" и НЕ ВМЕЩАЕТСЯ ни в хранилище "графических образов", ни в хранилище "строк кода" в моём мозгу.
Но! ПОСКОЛЬКУ этот код ХОРОШО и плотно покрыт тестами - мне и НЕ НАДО "его помнить".
Я ВСЕГДА могу посмотреть на ТЕСТЫ и понять - "как это работает" и "зачем это нужно".
ВСЁ! Мне НЕ НАДО "помнить код" и его детали.
Мне ДОСТАТОЧНО взят тесты и "перезагрузить" мой "кеш мозга".
ОЧЕНЬ УДОБНО. Для МЕНЯ ЛИЧНО.
Если кому-то этот подход - ИНТЕРЕСЕН - обращайтесь - могу попробовать и вас "прозомбировать".
P.S. А тут за рамками "выступления" осталось "аспектно-ориентированное программирование".
P.P.S. в том же самом проекте, где "нет UML" - нет и "нормальных тестов". И отчасти поэтому - он "тяжело программируется". Хотя и в РАЗЫ меньше других проектов.
Тесты как примеры, которые показывают КАК использовать тестируемый код, и которые показывают ЧТО тестируемый код делает -- это ОЧЕНЬ классная мысль. И сильная..
ОтветитьУдалитьСпасибо )
:-) пожалуйста :-)
ОтветитьУдалитьхотя конечно "это не я придумал"...
Но!
"я вот пытаюсь "вспомнить" что код делает - и для чего вообще проектировался - смотрю не реальное приложение, где "чёрт ногу сломит" в поисках, а тест.. отдельностоящий"
Ну и конечно - у нас тесты гоняются КАЖДЫЙ ДЕНЬ - посему никакая функциональность "не протухает", она либо ПОДДЕРЖИВАЕТСЯ, либо ВЫКИДЫВАЕТСЯ за ненадобностью.
ОтветитьУдалитьЗнание становится научным, если оно инвариантно относительно контекста (либо контекст достаточно широкий).
ОтветитьУдалитьПишем тест к классу, пишем класс. Вопрос: если мы НЕ пишем класс. Де-факто TDD в данной интерпретации жёстко накладывает условия по части выборе объектной парадигмы.
Начинают вырисовываться чертежи большой торпеды в корабль Delphi (в каноническом виде дизайн-проекта): Form1->Button1->OnClick. У нас НЕТ класса (класс формы, понятно, не в счет). Нет класса - нет теста. Нет теста - нет TDD. Шанс спастись от этой торпеды - сделать "летучий корабль". Можно ли применить модель TDD к не-классово-объектной функциональности?
И, конечно, нельзя не лягнуть "классиков". (цитата)
"«А что если я ошибся и мне придется изменить это решение в будущем? Какие будут последствия?». Если некоторое решение размазано ровным слоем по всему приложению, то стоимость его изменения будет огромной, а значит это решение является архитектурным.""
Делать заключение о качестве архитектуры на основе возможности тестирования отдельных элементов???? Модифицируемость - лишь один из показателей нефункционального качества. Жесткость связей гарантирует стабильную простоту системы.
Не верите? Тогда - зеркало в студию.
DBGrid->DataSource->TDataSet - очень жёстко. Как только предложили LiveBindings, пошла волна протестов (понятно, почему). Отсюда простой вывод. "Качество архитектурного решения из-за ослабления "контроля" достигается за счёт дополнительных усилий". Разумно ли их тратить? Если технологическое устаревание опережает сроки пересмотра архитектуры.... зачем огород городить? Возникает метафора "золотого унитаза" :)
Итак, господа, на повестке дня 2 вопроса:
1) TDD вне объектно-ориентированного программирования (но - object-based, form1...button1...onclick1)
2) ошибки классиков или "переусложенная" архитектура
"Пишем тест к классу, пишем класс. Вопрос: если мы НЕ пишем класс."
Удалитьмы ВСЕГДА пишем КЛАСС - класс функциональности
а не класс в терминах ООП
"DBGrid->DataSource->TDataSet - очень жёстко"
и ПЛОХО ТЕСТИРУЕМО.. факт
"Разумно ли их тратить?"
ДАЛЕКО НЕ ВСЕГДА разумно
тут вопрос встаёт - "а какой цикл модификации/поддержки кода"
если мы его "вообще не трогаем", то наверное ИМЕННО этот код и не надо тестировать