Предпочтительно ли дизайн сверху вниз или снизу вверх?

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

На практике лучше всего сочетать два метода: начинается с спецификации высокого уровня, чтобы полностью указать знания домена, его связь и ограничения. Как только проблема будет понята, создаются минимальные строительные блоки для создания системы.

Процесс:

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

выглядит совершенно нормально для меня (со спецификациями, как планы). У этого есть свои недостатки, но именно поэтому мы получили итеративное развитие: вместо того, чтобы тратить время на одну фазу, говорит, анализ требований, чтобы изучить все возможные вещи в области знаний, которые подвергаются изменениям (возможно, ежедневно), мы немного анализируем, немного дизайна, а затем реализовать его.

Другим способом является то, что каждая итерация представляет собой мини-водопад, где анализ выполняется через несколько дней (или неделю). То же самое касается дизайна. Остальное время тратится на реализацию. Есть ли что-то по своей сути неправильно с принципом «сверху вниз» в сочетании с итеративным развитием?

В своем эссе Программирование снизу вверх , Пол Грэм, кажется, поощряет сборку снизу полностью или программирует ее снизу но не на этапе анализа /проектирования требований:

  

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

Насколько я понимаю, он имел в виду, что Lisper по-прежнему выполняет сверху вниз дизайн, но программа снизу вверх, это правда? Еще один момент, который он написал:

  

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

Означает ли это, что в течение периода написания программы в Lisp вы получаете общий инструмент?

30 голосов | спросил Amumu 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 12:46:23 +0400000000pmSun, 12 Feb 2012 12:46:23 +040012 2012, 12:46:23

5 ответов


32

Сверху вниз - отличный способ описать то, что вы знаете, или перестроить вещи, которые вы уже создали.

Самая большая проблема сверху вниз заключается в том, что довольно часто просто нет «вершины». Вы измените свое мнение о том, что система должна делать при разработке системы и при изучении домена. Как может быть ваша отправная точка того, что вы не знаете (то есть, что вы хотите, чтобы система выполняла)?

«Местный» сверху вниз - это хорошо ... некоторые соображения перед кодированием явно хороши. Но думать и планировать слишком много не так, потому что то, что вы предполагаете, не является реальным сценарием (если вы уже не были там раньше, то есть если вы не строите, а перестраиваете). Глобальный сверху вниз при создании новых вещей - просто бред.

Снижение должно быть (глобально) подходом, если вы не знаете 100% проблемы, вам нужно только известное решение для кодирования, и вам не нужно искать альтернативные решения.

Подход Lisp - это дистиллированный снизу вверх. Вы не только строите снизу вверх, но также можете формировать кирпичи так, как вам нужно. Ничего не исправлено, свобода полна. Конечно, свобода берет на себя ответственность, и вы можете сделать ужасные вещи, злоупотребляя этой силой.

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

Пример вашего веб-сервера. Теперь, в 2012 году, это четко определенная проблема, у вас есть спецификации, которым нужно следовать. Веб-сервер - это просто проблема с реализацией. Особенно, если вы нацелены на создание веб-сервера, который, по существу, идентичен другому gajillion веб-серверов, которые находятся там, тогда ничего действительно неясно, кроме некоторых мелочей. Даже ваш комментарий к RSA по-прежнему говорит о четко определенной проблеме с официальными спецификациями.

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

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

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

Что такое правило выравнивания? Вам решать. Что такое шаблон, как его представлять? Вам решать. Как выровнять детали? Вам решать. Могут ли детали быть «согнуты»? Это зависит, некоторые нет и некоторые да, но, конечно, не слишком много. Что делать, если материал слишком деформирован для части, чтобы разрезать его приемлемо? Вам решать. Все ли рулоны материала идентичны? Конечно, нет, но вы не можете нападать на пользователя, чтобы адаптировать правила выравнивания для каждого рулона ... это было бы непрактичным. Какие фотографии видят камеры? Материал, что бы это ни значило ... это может быть цвет, он может быть черным над черным, где только световой рефлекс делает картину очевидной. Что означает означает распознать шаблон? Вы решаете.

Теперь попробуйте создать общую структуру решения для этой проблемы и дать цитату в деньгах и времени. Моя ставка заключается в том, что даже ваша системная архитектура ... (да, архитектура) будет неправильной. Оценка стоимости и времени будет случайным числом.

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

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

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

Новые сложные программные системы выращиваются, а не разрабатываются. Время от времени кто-то начинает разрабатывать большую новую сложную программную систему с нуля (обратите внимание, что с большим сложным программным проектом есть только три возможности: а] спецификация нечеткая, b] спецификация неправильная и противоречивая или c] и ... и чаще всего [c] имеет место).

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

Означает ли это, что я думаю, что вы должны думать только о коде? Конечно нет. Но, на мой взгляд, строительство должно начинаться снизу (кирпичи, бетонный код) и должно подниматься ... и ваше внимание и внимание к деталям должно в некотором смысле «исчезать», когда вы становитесь дальше от того, что у вас есть. Сверху вниз часто представлены так, как будто вы должны сразу же установить один и тот же уровень детализации всей системы: просто держите его на каждом узле, пока все не станет очевидным ... на самом деле модули подсистемы «выросли» из подпрограмм. Если у вас нет предыдущего опыта в конкретной проблеме, то ваш верхний дизайн подсистемы, модуля или библиотеки будет ужасен. Вы можете создать хорошую библиотеку, как только вы знаете, какие функции включить, а не наоборот.

Многие идеи Lisp становятся все более популярными (функции первого класса, закрытие, динамическая типизация по умолчанию, сбор мусора, метапрограммирование, интерактивное развитие), но Lisp по-прежнему сегодня (среди языков, которые я знаю) совершенно уникален тем, насколько легко для формирования кода для того, что вам нужно.

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

С C ++ вместо этого вы можете получить кучу экспертов C ++, говорящих вам, что параметры ключевого слова не так полезны или невероятно сложная, сломанная, наполовину поддерживаемая реализация шаблона, которая действительно не так полезна. Являются ли классы класса C ++ первоклассными? Нет, и вы ничего не можете с этим поделать. Можете ли вы иметь интроспекцию во время выполнения или во время компиляции? Нет, и вы ничего не можете с этим поделать.

Эта гибкость языка Lisp - это то, что делает его отличным для восходящего здания. Вы можете создавать не только подпрограммы, но также синтаксис и семантику языка. И в известном смысле сам Лисп восходящий.

ответил 6502 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 14:06:59 +0400000000pmSun, 12 Feb 2012 14:06:59 +040012 2012, 14:06:59
6

Я не уверен, как этот ответ применим к Lisp, но я только что закончил читать Гибкие принципы , «Шаблоны и практика» и автора, Дядя Боб , решительно выступает за нисходящий подход для C # (также применимый к C ++), с которым я полностью согласен.

Однако, в отличие от некоторых других ответов, которые пришли к выводу, что подход «сверху вниз» означает, что в первом взаимодействии вы только доставляете документы и общий дизайн, книга указывает на другой метод: TDD в сочетании с эволюционным дизайном.

Идея состоит в том, что вы начинаете с вершины и определяете свои наивысшие уровни абстракции (или местный максимум), и как только они определены, вы делаете их полезными для работы, так что функция №1 немедленно работает. Затем, когда вы добавляете все больше и больше функций, вы реорганизуете свой код и разрабатываете дизайн по мере необходимости, всегда сохраняя осведомленность о SOLID . Таким образом, у вас не будет слишком много слоев абстракции, и вы не закончите низкоуровневый дизайн, который не соответствует общей архитектуре. Если вы не знаете, что это значит, книга, о которой я упоминал выше, имеет целую главу с примером, где разработчики берут понятия и начинают с UML-диаграмм и классов низкого уровня, только для того, чтобы реализовать половину этих классов, не нужно, как только начинается кодирование. В сущности, при таком подходе низкоуровневый код естественно сбрасывается, поскольку в проекте определены более детализированные детали.

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

Если вам интересно узнать больше о XP и эволюционном дизайне, вот хорошее чтение от Мартина Фаулера, еще одного великого автора: " Is Design Dead? "

ответил DXM 13 FebruaryEurope/MoscowbMon, 13 Feb 2012 02:21:02 +0400000000amMon, 13 Feb 2012 02:21:02 +040012 2012, 02:21:02
3

Для меня наиболее важные замечания, сделанные Полом Грэмом в его статье, следующие:

  

[...] Лисп-программисты [...] следуют принципу, который можно назвать восходящим дизайном - изменение языка в соответствии с проблемой. В Lisp вы не просто записываете свою программу в сторону языка, но также строите язык в соответствии с вашей программой.

Или, как известно в кругах C ++: Дизайн библиотеки - это языковой дизайн (Bjarne Stroustrup)

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

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

ответил pillmuncher 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 20:01:31 +0400000000pmSun, 12 Feb 2012 20:01:31 +040012 2012, 20:01:31
2

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

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

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

Обратите внимание, что в отличие от реальных автомобилей и реальных колес, если вы создали одно программное обеспечение «колесо», вы создали бесконечное число из них.

Больше по дизайну сверху вниз: в то время как вам нужно начинать с этого, я чувствую себя обязанным указать, что если вы не можете создать колесо, вам нужно найти это до вы много работаете над своим автомобилем. Поэтому вам нужно работать снизу вверх почти параллельно с работой сверху вниз. Кроме того, зная, что вы можете построить колесо, может предложить много проектов, о которых вы бы даже не подумали, например, трейлер-трейлер. Я думаю, что подход сверху вниз должен доминировать, но с легким прикосновением very .

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

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

ответил RalphChapin 16 FebruaryEurope/MoscowbThu, 16 Feb 2012 19:45:51 +0400000000pmThu, 16 Feb 2012 19:45:51 +040012 2012, 19:45:51
1
  

Что не так с подходом сверху вниз в сочетании с итеративным развитием?

Использование подхода сверху вниз с итеративной разработкой не дает никакого рабочего кода в первых итерациях. Он предоставляет проектные документы и такие, которым заказчику будет непросто с предоставлением обратной связи. Ответы вроде: «Да, я думаю (это слишком абстрактно для меня)» не поможет вам в дальнейшем конкретизировать специфику желаемой системы клиентом.

Вместо этого вы создаете общий обзор того, что запрашивается. (Требования) для использования в качестве общего руководства для определения конечного продукта и того, что заслуживает приоритета. Оттуда вы создаете рабочие продукты для каждой итерации, которые клиент может фактически поиграть, чтобы понять, было ли это то, что они имели в виду. Если нет, то это не будет проблемой, поскольку не было потрачено на сотню часов на разработку системы, которая отличается от того, что просит клиент.

  

Пол Грэм поощрял сборку снизу вверх полностью? Или просто запрограммировать его снизу вверх, но не на этапе анализа требований /desing?

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

  

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

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

ответил Beanow 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 14:14:46 +0400000000pmSun, 12 Feb 2012 14:14:46 +040012 2012, 14:14:46

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132