Тут thesz узнал из достоверных источников, что я решаю свою задачку на Эрланге, и уже запустил рекламую компанию:
http://thesz.livejournal.com/648397.htmlhttp://thesz.livejournal.com/646592.html Решение и в самом деле почти готово - мне осталось научиться запускать приложения Эрланга из командной строки и протестировать стандартный ввод/вывод, а также прогнать системный тест. Пока же, я расскажу про свою задачку, дизайн, и о том, что такое дизайн в ФП.
Сначала о задачке.
Эта задача была разработана мной во время работы в CQG, для целей фильтрации С++ программеров перед собеседованием, требования были следующие. Во-первых, она должна быть простой алгоритмически. Любой мало-мальски грамотный инженер должен быть в состоянии написать работоспособную программу. Во-вторых, она не должна требовать много времени для решения - 2-3 дня максимум, и решение не должно занимать много кода, а то затрахаем тестируемого и сами затрахаемся проверять. В-третьих, в отличии от подавляющего большинства аналогичных задач, она должна проверять навыки проектирования и дизайна. В четвертых, должны также проверяться навыки работы с требованиями и техничскими заданиями (на английском языке). Вот что получилось - мини-эксель из командной строки. thesz сделал перевод этой задачи на русский:
http://thesz.livejournal.com/280784.html thesz тут периодически совершает набеги на лагерь эрлангистов, и недавно хотел увидеть Это, идиоти... (тьфу!), идиоматическое для Эрланга решение этой задачи. Так как я один из идейных предводителей эрлангистов на RSDN, то мне пришлось принять вызов. Заодно - было бы интересно изучить возможности Эрланга в области дизайна, чтобы было о чем пофлеймить с фоннатами ООП, а на чем это делать как не на моей специально для этого созданной задачке. Кроме того, как заметил thesz, я уже два года как "не держал в руках компилятор" (менеджер я), и мне захотелось размять мозги, а все языки кроме Эрланга я уже забыл. А Эрланг настолько прост, что его забыть просто нельзя. Короче, все сошлось, и я взялся за решение.
Итак, основная сложность в ней не алгоритмическая - задача в общем до чрезвычайности проста, а в дизайне. Слово, мягко говоря, популярное, его употребляют все программисты. Часто - в составе словоснчетания "ОО дизайн". Дальше обычно идут "паттерны", и прочие страшилки. Однако, общего внятного понимания смысла термина "дизайн" не существует. Мы попробуем его определить, причем, в отрыве от ОО. Что же такое дизайн.
Будем пользоваться понятиями "связности" и "ошибки". Подход от классификации ошибок - вообще наиболее правильный при анализе процесса разработки. О чем идет речь (внимание! это важный момент). НЕ НАДО думать о понятиях архитектура, дизайн, кодирование и отладка как об активностях и фазах разработки. Во-первых, это неправда, во-вторых - это будет вас сбивать. Суть в другом. Вот вы нашли в программе ошибку. Относительно нее, вы можете сказать, что это за ошибка - ошибка в алгоритме (детальный дизайн - подробнее ниже), ошибка по невнимательности (кодирование), утечка памяти или крэш (обычно - ошибка кодирования), ошибка в декомпозиции (дизайн), или жосткая ошибка в изначальном подходе (архитектрура). Короче говоря, перечисленные понятия мы рассматриваем *как классификатор ошибки*. И тогда все становится просто, и встает на свои места.
Дизайн не надо путать с архитектурой, что, кстати, является еще более мутным термином чем дизайн. Не будем определять архитектуру, однако заметим, что вопросы вроде выбора платформы, технологий, библиотек, подразбиение программного компекса на сервисы - это безусловно вопросы архитектуры. Ошибки в них дорого обходятся. Пример - я опишу архитектуру среды для торговых роботов "Одиссей", которая разрабатывалась в CQG.
MS SQL применяется для хранения всех данных программы и ее состояния - в том числе исходных текстов алгоритмов торговых роботов, конфигурации торговых роботов, исполняемых файлов торговых роботов - в общем, всего (это, кстати, была ошибка номер раз - надо было в фаловую систему сохранять в формате XML). Торговые роботы пишутся, отлаживаются, и выполняются при помощи MS Visual Basic for Applications, который используется как в качестве рантайма, так и в качестве среды разработки (это была ошибка номер два - надо было свой язык делать сразу). В качестве источника котировок выступает сетевой клиент CQG, который реализует интерфейс OLEDB Provider. Он же применяется для заявок на покупку-продажу. Сам "Одиссей" пишется как набор из большого количества изолированных COM-классов (это была ошибка номер три - надо было выставить COM-интерфейс из монолитной плюсовой программы).
Вот, в кратце я описал архитектуру Одиссея, и пункты, перечисленные мной как ошибки, привели к увеличению трудоемкости проекта более чем в два раза, и ухудшению его потребительских свойств. Проект в результате был закрыт. Вот, господа, это называется архитектура. Теперь о дизайне, который не архитектура.
So who the fuckin guy design is?! Ошибки дизайна всегда менее страшны, чем архтектурные, и даже есть распространенное мнение, что их можно легко исправить "рефакторингом". Не будем с этим спорить, вместо этого, чтобы навести порядок в терминологии, воспользуемся светлой мыслью из PSP/TSP. А именно, design бывает просто design, и detailed design. Detailed design - это ваши агоритмы и структуры данных. Design - это ваша декомпозиция на более крупном уровне, способ структурирования программы, подразбиения на модули, функции, типы, и классы, ну или что там у вас есть.
Итак, эта задача на дизайн. Сложности в алгоритмах там нет, архитектурных ошибок допустить нельзя, таким образом - вся сложность в дизайне. В том, как вы будете структурировать ваш код, насколько простым он будет в понимании, насколько дешев в модификации, развитии, поддержке. Цена внесения изменения при хорошем дизайне невысока, при плохом - просто чудовищна ("хрупкий дизайн"). При хорошем дизайне можно вести разработку бОльшим количеством разработчиков, чем при плохом. Все перечисленное присходит не потому, что применяются паттерны GoF, а по причине разбиения задачи на *слабосвязные компоненты*. Связность - вот что в дизайне ключевое. Мы должны выделить слабосвязные фрагменты задачи, и описать решение таким образом, чтобы связность между его составными частями была настолько слаба, насколько это возможно.
Вот, об этом и пойдет речь в следующем посте - как именно мы решим проблему хорошего дизайна на Эрланге, на примере моей задачки с кодовым названием "Problem K".