[ <<<
| 1
| 2
| 3
| 4
| 5
| 6
| >>>
]
Где структурное проектирование дает сбои
Теперь, когда мы знаем то, что ищем, когда создаем программное обеспечение, можно оценить качество работы существующих методов.
Краткий обзор нисходящего структурного проектирования
Нисходящее проектирование (известно также как нисходящая декомпозиция или пошаговое усовершенствование) отталкивается от общего утверждения относительно процесса, определяемого решаемой проблемой, к постепенно детализируемым утверждениям относительно каждой специфической задачи в этом процессе.
На рис. 1 приведена типовая нисходящая декомпозиция "Подпрограммы импорта данных".
Обратите внимание, что разделение осуществляется по строго функциональным линиям; мы
заботимся лишь о том, что делает каждый модуль.
Рис. 1. Пример нисходящей функциональной декомпозиции
Нисходящие проектирования работает хорошо, потому что оно позволяет нам одновременно сосредотачиваться на меньшем количестве деталей. Это логичная методика, которая поощряет организованную доводку системы и уменьшает уровень сложности (степени интеграции) на каждой из последующих стадий проекта. По очевидным причинам, нисходящие проектирования подходит лучше всего тогда, когда применяется к проблемам, которые имеют ясно выраженный иерархический характер. К сожалению, многие из реальных проблем не иерархические. Проект, основанный на построении сверху вниз, имеет также и другие ограничения, которые станут очевидными при разработке и сопровождении больших программных систем.
- Функциональную точку зрения трудно развивать.
- Реальные системы трудно охарактеризовать функционально.
- Фокусирование на функциональности теряет из виду данные.
- Функциональная ориентация производит код, менее пригодный для многократного использования.
Проблемы метода
Функциональную точку зрения трудно развивать
Каждая реальная система изменяется и эволюционирует. Нисходящий подход создает хорошую программную модель для исходных требований к системе. Но система изменяется, что ведет к появлению новых требований. Поэтому функциональная архитектура постепенно становится неуправляемой. Поскольку программное обеспечение разработано вокруг относительно фиксированной древовидной структуры (рис. 1), изменения обычно требуют длительного сокращения и прививания. Чистый и хорошо разработанный проект быстро становится "ужастиком", повествующим о новых и повисших связях. Сопровождение становится все более трудным, поскольку первоначальная архитектура медленно умирает с каждой новацией или изменением требований.
Реальные системы трудно охарактеризовать функционально
Многие из больших систем не имеют верхнего уровня. Например, система управления базой данных включает инструментальные средства для запроса данных, изменение данных, хранение непротиворечивых данных, и т.д. Нет какой-либо функции, являющейся самым важным звеном в этой системе. Определение этой системы в терминах одной функции верхнего уровня искусственно и приводит к чрезмерно сложным и неадаптивным архитектурам.
"Одним из наиболее важных решений, принимаемым при разработке системы, является предположение о том, как сделать декомпозицию верхнего уровня. При нисходящем подходе это решение необходимо принять в начале процесса проектирования, то есть тогда, когда имеется минимум информации... Возможно, наиболее серьезная слабость в том, что нисходящее функциональное проектирование требует, чтобы система характеризовалась одной функцией наверху. Это сомнительное требование для многих современных систем, управляемых событиями".
Фокусирование на функциональности теряет из виду данные
Из примера, представленного выше (рис. 1), видно, что нисходящий проект не фиксирует информацию о данных, используемых в программе. Функции же всегда что-то делают с данными. Обычно, одни и те же данные разделены между функциями (например, модификации, удаления, вставки и запроса, работающих с таблицей базы данных). Так как декомпозиция только высвечивает функциональные аспекты проблемы, влияние структур данных на проблему оказывается потерянным.
Функциональная ориентация производит код, менее пригодный для многократного использования
При нисходящем проектировании осуществляется непрерывное дробление проблемы на все более простые части. Каждый кусок анализируется и специфицируется отдельно без сильной связи между ним и остальной частью системы. Это является одной из причин, по которой проектирование "сверху вниз" так эффективно на этапе анализа проблемы. Данный метод работает хорошо при начальном проектировании системы, и помогает получить спецификации для выявления и решения проблемы. Однако каждый элемент программы разработан только с ограниченными требованиями к памяти. Так как маловероятно, что точно такие же требования встретятся при решении следующей проблемы, проект программы и код не могут быть обобщены для многократного использования.
Нисходящее проектирование не препятствует созданию общих подпрограмм, которые разделяются между многими программами; но оно не поощряет этот процесс. На самом деле, идея объединения повторно используемых программ в систему проявляется в восходящем подходе, являющимся обратной альтернативой нисходящему стилю.
Но что сказать о библиотеках подпрограмм?
Конечно, есть области, где функциональный подход работает хорошо. Эта тенденция проявляется там, где:
- Большая группа схожих проблем может быть идентифицирована и сгруппирована вместе.
- Каждая из этих проблем относительно мала и может характеризоваться малым числом параметров.
- Каждая из проблем отличается от других (иначе говоря, унификация требует многократного использования проекта и его кода в каждой проблеме).
- Нет включения сложных структур данных (иначе концептуальная автономия каждого прикладного модуля была бы потеряна).
Области, которые соответствуют этим критериям, включают библиотеки математических подпрограмм для решения проблем линейной алгебры и дифференциально-разностных уравнений.
Трудности с этим подходом возникают тогда, когда необходимо иметь дело с более сложными проблемами Вам приходится иметь индивидуальные подпрограммы со многими параметрами или много малых подпрограмм с небольшим числом параметров. В первом случае большое число параметров будет делать подпрограмму трудно используемой и трудно сопровождаемой. Код, скорее всего, будет включать многочисленные вложения операторов if ... endif или case ... endcase. Это кошмар при таких модификациях, как новые добавления к пространству состояний. Во втором случае, большое количество подпрограмм будет затруднять их запоминание, что затрудняет использование. Более того, будет иметься много общего кода, рассеянного среди этих многих подпрограмм (так как многие из них будут очень похожи). Этот общий код будет трудно модифицировать и поддерживать. Библиотеки подпрограмм полезны в некоторых областях, но они не решают общих проблем, присущих структурному, нисходящему проектированию.
Итог по структурному проектированию
Для подведения итогов я процитирую Мейера Бертрана (Bertrand Meyer), так как вряд ли скажу лучше его:
Нисходящее функциональное проектирование плохо адаптируется к разработке крупных (больших) программных систем. Нисходящее проектирование остается полезной парадигмой для малых программ и индивидуальных алгоритмов..., но оно практически не масштабируется на большие системы. Смысл не в том, что Вы не можете разрабатывать систему сверху вниз: можете. Но, выторговывая для себя краткосрочное удобство за длительную негибкость, Вы некорректно нагромождаете одну функцию над другой и (достаточно часто) функциональный интерфейс над более важными параметрами системы. Вы теряете из виду аспект данных, и Вы жертвуете возможностью многократного использования.
[ <<<
| 1
| 2
| 3
| 4
| 5
| 6
| >>>
]
|