Чтобы достичь знания, добавляй что-то каждый день;
чтобы достичь мудрости, каждый день отбрасывай что-то.
Лао Цзы
чтобы достичь мудрости, каждый день отбрасывай что-то.
Лао Цзы
Пытаясь изменить меню загрузчика FreeBSD я столкнулся с новым для меня языком - Форт. В результате "гугления" по теме мне попалась достаточно древняя книжка Лео Броуди “Способ мышления - Форт”. Она не является учебником по Форту и, кроме того, была издана в теперь уже далеком 1984 году (а на русский переведена в 1993), но я все равно решил заглянуть внутрь и не пожалел. Помимо материала относящегося непосредственно к Форту, книжка содержит советы, рассуждения на тему методологий программирования и проектирования программ вообще. Изложенные мысли мне показались очень интересными, поэтому предлагаю вашему вниманию цитаты из этой замечательной книги. Обратите внимание, как давно, по компьютерным меркам, были высказаны эти мысли, некоторые из которых со временем приобрели статус “прописных истин”.
- Разработка "с вершины"
[...] Методология, называемая "разработкой сверху-вниз", утверждает, что модули следует строить, начиная с самого общего, главного и далее прорабатывать до уровня самых мелких модулей.
Последователи такого подхода могут засвидетельствовать возникновение позорно огромных потерь времени в результате ошибок в планировании. На горьком опыте они познали, что попытки корректировать программу после того, как она была написана - такая практика известна как "наложение заплат" - подобны попытке запереть двери конюшни после того, как лошадь уже понесла. Поэтому как контрмеру они предлагают следующее официальное правило программирования сверху-вниз:
Не писать ни строчки текста до тех пор, пока план не проработан до мельчайших деталей.
Вследствие таких трудностей при внесении изменений в однажды написанные программы, все упущения в проекте должны быть устранены на стадии предварительного планирования. В противном случае могут быть затрачены человеко-года усилий по написанию кода, который потом нельзя использовать.
- Постепенная детализация*
Один из подходов, существенно опирающихся на использование подпрограмм, называется "постепенной детализацией". Идея состоит в том, что Вы начинаете с написания скелетной версии программы, использующей естественные имена процедур и структур данных. Затем Вы пишете версии для каждой из именованных процедур. Процесс продолжается в сторону большего уровня детализации до тех пор, пока процедуры не смогут быть выражены непосредственно на компьютерном языке.
При каждом шаге программист должен принимать решения об используемых алгоритмах и о типах структур данных, которые обрабатываются этими алгоритмами. Такие решения должны приниматься параллельно. Если выбранный путь оказался непригодным, программист должен набраться мужества вернуться назад насколько требуется и заново проделать работу.
Обратите внимание, что при постепенной детализации Вы не можете реально запустить какую-либо часть программы до тех пор, пока не будут написаны ее компоненты самого нижнего уровня. Обычно это значит, что программу нельзя проверить до тех пор, пока она не будет полностью закончена. Заметьте также: постепенная детализация заставляет Вас прорабатывать все детали структур управления на данном уровне перед переходом на следующий уровень вниз.
* Niklaus Wirth, "Program Development by Stepwise Refinement", Communications of ACM, 14, No.4(1971), 221-27.
- Простота - главный показатель, по которому рекомендуется выбирать среди альтернативных проектов для обеспечения снижения времени на отладку и модификацию. Уровень простоты может быть улучшен за счет разбиения системы на отдельные куски так, чтобы каждый из них мог рассматриваться, применяться, утверждаться и изменяться с минимальным влиянием на или изменениями в других частях системы.
- [...] решения о передаче управления не должны доминировать в проекте. Как мы убедимся, поток управления - это поверхностный аспект проблемы. Мизерные изменения в исходных требованиях могут существенно изменить структуры управления в программе и потребовать многих лет ее углубленного "перекапывания". Но, если проект программы ориентирован на что-то другое, например, на потоки данных, то изменения в планах не будут столь разрушительными.
- В работе*, опубликованной еще в 1972 году, д-р Дэвид Л. Парнас показал, что критерием для разбиения на модули должны быть не шаги в процессе, а куски информации, которые, возможно, будут меняться. Модули должны использоваться для сокрытия такой информации. [...] Упрятывание информации - а не структура принятия решений или иерархия вызовов - вот что должно лежать в основе проектирования!
* David L. Parnas, "On the Criteria To Be Used in DecomposingSystems into Modules," Communications of the ACM, December 1972.
- Разаработка, при которой модули группируются в соответствии с потоком передачи управления, не готова к быстрым изменениям в проекте. Структура, построенная в соответствии с иерархией управления, является поверхностной. Готовность к восприятию изменений может обеспечить проект, в котором модули формируются по признаку объединения потенциально изменяемых вещей.
- [...] экспериментирование проявляет себя более надежным в деле приближения к истине, нежели строительство догадок при планировании.
- Любой, кто скажет Вам, что существует некоторое определенное количество фаз в цикле разработки программного обеспечения, будет глупцом.
- Превосходным свидетельством в пользу модели проектирования вида разработка-проверка является эволюция. От протоплазмы к головастику и к человеку, каждый вид на этом пути состоит из функциональных, жизнеспособных существ. Создатель явно не выглядит проектировщиком "сверху-вниз".
Начинайте с простого. Пусть оно заработает. Поймите, что именно Вы пытаетесь получить. Добавляйте сложность понемногу, насколько это необходимо для выполнения требований и ограничений. Не бойтесь начинать сначала.
Разработка программ на Форте в первую очередь направлена на поиск самого простого решения данной проблемы. Это достигается реализацией выбранных частей задачи раздельно и игнорированием возможно большего числа ограничений. Затем вводятся одно или несколько ограничений, и программа модифицируется.
Kim Harris, "The FORTH Philosophy"
Dr. Dobb's Journal, Vol. 6,
Iss. 9, No. 59 (Sept. 81), pp. 6-11. - [...] Вы не знаете толком, что делаете, до тех пор, пока один раз это не пройдете. Мой опыт показывает, что наилучший способ написать программу - это написать ее дважды. Выкиньте первую версию, приняв ее за набросок.
- [...] Когда я строю прототип, я делаю это с твердой уверенностью в том, что не буду использовать ни строчки из текста прототипа в конечной программе. Эта вынужденная "переделка" почти всегда приводит к значительно более простым и более элегантным законченным программам, даже если последние написаны на чем-то, отличном от Форта.
- Обобщенность обычно приводит к сложности. Не обобщайте свое решение более, чем это необходимо; вместо этого предусматривайте возможность изменения.
- Если Вы можете улучшить постановку задачи, следует не упускать такую возможность. Гораздо приятнее перепроектировать мир, нежели реализовывать его "в лоб".
- Проектирование по компонентам делает мало значащим то место, с которого Вы начинаете. Решая, с чего начать проектирование, ищите:
- места, для которых требуется максимум творчества (места, где вероятность изменений наиболее велика)
- места, которые дают самую удовлетворительную отдачу
- места, которые могут в дальнейшем наиболее сильно повлиять на другие области или которые определяют, может ли задача вообще быть разрешена
- вещи, которые следует продемонстрировать заказчику для установления взаимопонимания
- вещи, которые можно показать тем, кто дает деньги, если это нужно для продолжения финансирования.
- Более сложные проблемы предоставляют множество возможных путей для обращения с поступающими данными. Как узнать, какой маршрут приведет Вас ближе к решению? Неизвестно. Этот класс задач лучше решается при проработке назад. [...] если задача нерешаема, проработка назад помогает Вам быстро доказать отсутствие ее решения.
- Если у Вас есть что-то, чему Вы не в состоянии присвоить единое имя, не название с внутренними тире, а имя, то значит это - не четко сформированная концепция. Возможность присваивания имени является обязательной частью декомпозиции. Естественно, Вы должны глубоко понимать идею.
- [...] Такого рода подходы часто клеймятся как "трюкачество" (trick). В большой компьютерной индустрии трюки имеют плохую репутацию.
Трюк - это просто использование преимуществ некоторых свойств операции. Трюки широко применяются в инженерной области. Дымоходы тянут дым, используя преимущества того факта, что тепло поднимается вверх. Автомобильные шины обеспечивают трение, используя преимущества земного притяжения. Арифметико-логические устройства (АЛУ) пользуются знанием того факта, что вычитание числа - это то же самое, что прибавление его двоичного дополнения.
Эти трюки позволяют создавать более простые и эффективные конструкции. Их использование оправдано тем, что предположения, на которых они строятся, безусловно останутся в силе. Использование трюков становится опасным тогда, когда они зависят от чего-то, что вполне может измениться или не защищено упрятыванием информации.
- Не делайте проверок для чего-то, что не может произойти.
Много современных программистов осчастливлены задачей проверки ошибок. У функции нет необходимости проверять аргументы, передаваемые ей другим компонентом системы. Вызывающая программа должна сама нести ответственность за обеспечение нужных границ для вызываемого компонента.
- Остерегайтесь проверок на специальные случаи. [...] если Вы обеспечиваете непопадание пользователя в беду, то Вам не требуется постоянно проверять, не попал ли он все-таки в эту беду.
Другой хороший пример - это написание ассемблеров. Очень часто, даже если код операции может и не иметь ассоциированного с ним номера регистра, можно многое упростить, делая вид, что такой регистр есть - скажем, Регистр 0. Решение упрощается, когда производятся арифметические действия над ненужными битовыми полями. Просто запишите в них нули и продолжайте вычисления, которые Вы могли бы избежать, делая проверки на ноль и обходя их. Это - другая ипостась принципа "безразличности". Если Вам безразлично, то дайте безразличное число и используте его.
Каждый раз, когда у Вас возникает особая ситуация, попытайтесь найти алгоритм, для которого эта ситуация становится нормальной.
Чарльз Мур
- Использование логики и условных операторов в качестве существенного структурного элемента в программировании ведет к переусложненному, трудно управляемому и неэффективному коду.
- Выполняйте действие сразу, как только узнаете, что его выполнить необходимо, но не позже. Всякий раз, когда Вы устанавливаете флаг, спросите себя, зачем. Если ответ состоит в том, "чтобы знать, что мне надо сделать то-и-другое попозже", то задумайтесь, нельзя ли сделать то-и-другое теперь. Небольшое изменение структуры может существенно упростить Вашу разработку.
- Не устанавливайте флаг, устанавливайте данные.
- Не устанавливайте флаг, устанавливайте функцию.
Комментариев нет:
Отправить комментарий