А роль первой C в CRC для функциональных языков будут играть модули, получается? Кстати, хочется снова повторить свой вопрос про юнит-тесты и "глубокий" рефакторинг - как всёж ты считаешь их следует скрещивать?
Первая С - не только модули, но и АТД. У меня в Эрланге АТД языком не поддерживается, и я их заворачиваю в модули. В принципе - получается не хуже. Даже лучше - язык проще.
Насчет юнит-тестов - не надо мельчить, и все будет ок. Один тест на модуль - не всегда оправдано, именно по тем соображениям, о которых я писал. А вот делать тест "среднего уровня", для "полезных функций системы" - это уже хорошо, такой тест не отъедет.
Второй момент - юнит юниту рознь. В большой системе юнит тест будет масштаба системного теста для маленькой программы.
Короче, не надо мельчить с единицами тестирования. Лучше нашпиговать код проверкой инвариантов..
Ну тогда получается, что твоё помимание юнит-тестов несколько отличается от понимания TDD и иже с ним. Там же тестируют вплоть до функций. А у тебя выходит нечто промежуточное между функциональными тестами и мелкими юнит-тестами. Но в целом понятно, спасибо.
В моем понимании необходимость в юнит-тесте возникает при групповой и/или многоэтапной разработке, чтобы позволить исполнителям отлаживаться независимо. До сшивки фрагментов в большую систему.
Для микротирования есть инварианты в коде (что дешевле тестов - проверено), и, разумеется, Repl. Здесь моя позиция сходна с позицией Зефирова.
Эта методика замечательно работает и на С++ - разумеется, без Repl, но в плюсах у нас зато есть отладчик.
>> Дизайн в случае функциональной чистоты - удивительно простое и приятное занятие, не приходится морочится с состоянием, identity, и следующими из них схемами агрегации. Дизайн уже не является трудоемкой фазой разработки. Это меня изумляет.
Хм... А может это просто из-за того, что дизайн был "с нуля"? И был достаточно небольшим, чтобы помещаться в голове целиком? Если нужно что-то такое-эдакое дописать к серъезной существующей программе, не верится, что также легко получится... Особенно с объектной частью...
Нет, дело не в этом. Я специально решаю те задачи, которые я в прошлом очень удачно решал для С++ и ОО. Чтобы понаблюдать за собой, и сравнить возникающие проблемы и усилия.
Дело все в том, что в чистом коде нет ссылок, и, следовательно, агрегации. А из чего объектная можель состоит? Из отношений наследования, агрегации, ссылок, и распределения функций по классам. В случае чистого кода вы заняты только последним, и не можете налажать в первых пунктах принципиально. Поэтому все проще и дешевле.
Рефакторинг дешев, потому что нет разделяемого состояния - функции можно двигать между модулями не опасаясь последствий, они будут работать гарантировано.
Потом натягиваем на это объектную модель - определяем класс, котроый реализован чисто, используя ранее написанный чистый код. Вот у вас и выходит, что связность чистых модулей никак не зависит от связности классов - это совершенно независимые части.
Это, короче, без примера понять сложно. Я потом напишу.
Это большя честь для меня, однако - в этом виде - не стоит включать его методичку, потому что я (шепотом) этот код после последнего рефакторинга не отлаживал :). Там ошибки есть почти наверняка. Вот если его отладить - то будет хорошо.
Comments 19
Кстати, хочется снова повторить свой вопрос про юнит-тесты и "глубокий" рефакторинг - как всёж ты считаешь их следует скрещивать?
Reply
Насчет юнит-тестов - не надо мельчить, и все будет ок. Один тест на модуль - не всегда оправдано, именно по тем соображениям, о которых я писал. А вот делать тест "среднего уровня", для "полезных функций системы" - это уже хорошо, такой тест не отъедет.
Второй момент - юнит юниту рознь. В большой системе юнит тест будет масштаба системного теста для маленькой программы.
Короче, не надо мельчить с единицами тестирования. Лучше нашпиговать код проверкой инвариантов..
Reply
Но в целом понятно, спасибо.
Reply
Для микротирования есть инварианты в коде (что дешевле тестов - проверено), и, разумеется, Repl. Здесь моя позиция сходна с позицией Зефирова.
Эта методика замечательно работает и на С++ - разумеется, без Repl, но в плюсах у нас зато есть отладчик.
Reply
Хм... А может это просто из-за того, что дизайн был "с нуля"? И был достаточно небольшим, чтобы помещаться в голове целиком? Если нужно что-то такое-эдакое дописать к серъезной существующей программе, не верится, что также легко получится... Особенно с объектной частью...
Reply
Дело все в том, что в чистом коде нет ссылок, и, следовательно, агрегации. А из чего объектная можель состоит? Из отношений наследования, агрегации, ссылок, и распределения функций по классам. В случае чистого кода вы заняты только последним, и не можете налажать в первых пунктах принципиально. Поэтому все проще и дешевле.
Рефакторинг дешев, потому что нет разделяемого состояния - функции можно двигать между модулями не опасаясь последствий, они будут работать гарантировано.
Потом натягиваем на это объектную модель - определяем класс, котроый реализован чисто, используя ранее написанный чистый код. Вот у вас и выходит, что связность чистых модулей никак не зависит от связности классов - это совершенно независимые части.
Это, короче, без примера понять сложно. Я потом напишу.
Reply
Reply
Reply
Reply
Reply
Reply
Reply
Leave a comment