ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 06.11.2023
Просмотров: 916
Скачиваний: 6
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
296 дельного типа. Функциональное разбиение – это деление задачи на функции, выполняющие преобразования данных.
Разбиение STS обычно применяют для выделения первого слоя мо- дулей, а затем к каждому подмодулю применяется одна из трех страте- гий, причем выбор зависит от специфики подзадачи. Кроме этих страте- гий рекомендуется учитывать следующие правила: осуществлять возможно более глубокое разложение решений на час- ти; по возможности дольше не принимать решений, относящихся к де- талям представления данных; выбор проектировочных решений осуществлять на основе таких критериев, как эффективность, экономия памяти, ясность и согласо- ванность структуры; при выборе решений учитывать и возможные альтернативы, т.е. вме- сто одного решения следует разрабатывать семейство решений; сначала реализовать самые простые решения; построение системы производить небольшими шагами, на каждом шаге принимать решения минимальными порциями.
Теоретически процесс уточнения является однопроходным процес- сом, но практически это все же не так. На каждом шаге подходящие решения выбираются из некоторого множества альтернатив. На каком- либо из последующих шагов может выясниться, что это решение непри- емлемо. Поэтому в процессе работы приходится возвращаться назад и выбирать там другое решение, обеспечивающее возможность успешно- го продолжения. Каждый шаг в процессе уточнения соответствует неко- торой ступени абстракции или одному слою системы. В результате шага
1 получается слой 1, в результате шага 2 – слой 2 и т. д. Сой 0 представ- ляет систему в самой абстрактной (общей) форме. Все прочие слои слу- жат для определения модулей системы. В самом нижнем слое (n-м) мо- дули уточнены настолько, что их можно выразить с помощью имею- щихся языков программирования.
Как было уже сказано, каждый слой можно рассматривать как мно- жество компонентов, выполняемых с помощью некоторой виртуальной машины. Слой i реализуется машиной VM i с помощью слоев j (j < i).
Слой i следует рассматривать как логически полный, когда в нем можно задать выполнимый на машине M i алгоритм A i
, реализующий поста- новку задачи системы в предположении существования машины M i
Интерфейс между слоем i – 1 и более конкретизированным слоем i
“находится” в модулях, которые слой i предоставляет слою i – 1 и кото- рые зафиксируются при выборе решений во время проектирования. Та- ким образом, задача слоя i состоит в моделировании машины, сущест- вование которой предполагалось в слое i – 1.
Очевидно, что применение этого метода дает следующее: четко выделены отношения между модулями проекта; вообще говоря, реализация каждого модуля возможна при знании специфицированных отношений между его подмодулями;
297 в предположении правильности подмодулей правильность модуля может быть проверена независимо от остальной части системы и от способа дальнейшего разложения подмодулей; наконец имеется возможность обеспечить в весьма большой степени независимость программной системы от компьютера (машинного языка), перенося эту зависимость в нижние слои.
Следует иметь в виду, что функциональное и операционное разбие- ние – это в основном интуитивные процессы, во многом зависящие от разработчика. Что касается разбиения STS – это более сложный про- цесс, для выполнения которого можно использовать следующие реко- мендации [20]:
1. Основываясь на потоке данных в системе (задаче), представить ее структуру в виде нескольких (3 – 10) процессов.
2. Определить главный поток данных системы и главный выходной поток.
3. Проследить входной поток данных по структуре системы (моду- ля). При этом можно обнаружить два явления: входной поток изме- няет форму, становясь все абстрактнее по мере того, как идет про- движение по структуре процессов системы. В конце концов, будет найдена точка, где поток как будто пропадает. Точка, где он появля- ется в последний раз – точка наивысшей абстракции входного по-
тока.
4. Подобный анализ нужно выполнить для выходного потока дан- ных, двигаясь в обратном направлении, и определить точку, где вы- ходной поток появляется в самой абстрактной форме. Эти точки представляют особый интерес, поскольку они делят систему (мо- дуль) на наиболее независимые части.
5. Две найденные точки обычно делят систему на три части. Эти час- ти представляются модулями с соответствующими функциями. Оп- ределенные таким образом модули становятся подчиненными по от- ношению к модулю, разбиение которого выполняется.
6. Определяются сопряжения этих модулей на уровне качественного описания входных и выходных аргументов. Детали этих сопряжений будут определены при внешнем проектировании модулей.
Рассмотрев технологию проектирования по методу сверху-вниз, сле- дует задаться вопросом: когда прекратить разбиение системы, т.е. сколько уровней должно быть, или чему равно n? Этот момент опреде- ляется по следующему правилу: логика модулей должна стать интуи- тивно понятной. Это означает, что модуль, вероятно, будет содержать нее более 50 предложений [13, 32].
6.7.2. Проектирование снизу-вверх
В этом случае разработка осуществляется в направлении от деталей к целому, от отдельного через частное к общему. Если принцип сверху- вниз характеризовался разложением (декомпозицией) на модули, то те- перь, наоборот, проводится объединение (композиция) элементарных
298 компонентов в более сложные и таким образом строится программная система. Часто целью разработки в этом методе является повышение уровня языка программирования, а не разработка конкретной програм- мы. Это означает, что для данной предметной области выделяются ти- пичные функции, которые специфицируются, а затем программируются отдельные программные модули, выполняющие эти функции. Сначала в виде модулей реализуются более простые функции, затем создаются модули, использующие уже имеющиеся функции и т. д.
Действия разработчика в соответствии с таким подходом можно раз- делить на два этапа.
На первом этапе (шаг 1) предлагается состав компонентов, которые должны войти в систему. В общем случае это могут быть команды ма- шинного языка, если идет разработка с уровня физической машины.
Однако, как уже говорилось выше, мы будем рассматривать программ- ные системы одного языкового уровня, а именно языка прикладного программирования (не важно, какого конкретно). Будем считать, что на исходном уровне (M
1 для технологии снизу-вверх) задано некоторое множество элементарных компонентов, реализующих функции (опера- торы) первого уровня.
Виртуальная машина 1-го уровня представляется следующим обра- зом:
VM
1
= < M
1
, O
1
, D
1
>, где M
1
= { m
1j
| j = 1, 2, …, N
1
} – множество модулей уровня 1, N
1
– количество модулей уровня 1;
O
1
= {o
1j
| j = 1, 2, …, N
1
} – множество операторов модулей виртуаль- ной машины M
1
, в котором каждый оператор характеризуется опреде- ленной функциональной f
1j и синтаксической спецификацией s
1j кон- кретного модуля m
1j
: o
1j
< f
1j
, s
1j
> ;
D
1
= {d
1j
| j = 1, 2, …, N
1
} – множество операндов модулей M
1
, в ко- тором каждый операнд задан определенной синтаксической и семан- тической спецификацией ss
1j данных конкретного модуля m
1j
: o
1j ss
1j
На втором этапе (шаги 2 – n) последовательно, шаг за шагом разра- ботчик объединяет элементарные компоненты таким образом, чтобы реализовать более сложные функции и приблизиться к требуемой цели.
На последнем шаге должна быть получена искомая система. Процесс объединения может быть получен следующим образом:
1. Процесс состоит из дискретной последовательности шагов.
2. На шаге i в результате принятия решений S
i путем объединения компонентов M
i-1
уровня i – 1 строятся более сложные компоненты (мо- дули) m ij
M i
и соответствующие им множества операторов o ij и множества операндов d ij
Виртуальная машина i-го уровня представляется следующим обра- зом:
VM i
= < M i
, O i
, D i
>, где M i
= {m ij
| j = 1, 2, …, N i
} – множество модулей уровня i, N i
– количество модулей уровня i;
299
O i
= {o ij
| j = 1, 2, …, N i
} – множество операторов модулей вирту- альной машины M
i
, в котором каждый оператор можно представить как объединение некоторых операторов модулей ниже лежащего уров- ня: o ij o i-1 j
, j = 1, 2, …, N i-1
;
Функциональные f ij и синтаксические s ij спецификации конкретного модуля m ij определяются соответствующими спецификациями модулей ниже лежащего уровня:
F ij f i-1 j
, s ij s i-1 j
, j = 1, 2, …, N i-1
;
D
i
= { d ij
| j = 1, 2, …, N i
} – множество операндов модулей M
i
, в ко- тором каждый операнд можно представить как некоторое обобщение синтаксической и семантической спецификаций ss i-1 j данных тех мо- дулей m i-1 j
M i-1
, которые используются для построения соответст- вующих операторов модулей M i
3. Как это типично для процесса синтеза, решения S i принимаются на каждом уровне. Эти решения определяют указанные объединения: m ij
M
i
(S i
(O i-1 j
)
O i j
) & (S
i
(D i-1 j
)
D i j
), j = 1, 2, …, N
i
В этом процессе объединения также возможны возвраты на преды- дущие уровни синтеза. Дело в том, что неподходящие решения иногда проявляются лишь на самом последнем шаге. Тогда необходимо на од- ном из предыдущих шагов принять другое решение и с этого шага зано- во продолжать работу. Как уже отмечалось, принцип проектирования снизу-вверх при реализации и тестировании имеет то преимущество, что работа может быть начата с реализуемых (проверяемых) компонен- тов. Однако это конечно не означает, что к реализации можно присту- пить, не имея полного проекта системы.
6.7.3. Еще раз о проектировании архитектуры ПС на основе объектно-ориентированной и компонентной методологии
Автор статьи [11] Дж. Макгрегор отмечает, что современная архи- тектура предлагает развернутую и точную модель системы. Методики формирования программной архитектуры предполагают детальный ана- лиз системы перед ее реализацией. Такие методики, как Attribute Driven
Design (ADD) [7], гарантируют, что программное обеспечение, реализо- ванное на основе предварительно сформированной архитектуры, будет точно отвечать своему предназначению. Есть немало примеров исполь- зования архитектуры в стратегических целях.
Один из самых известных примеров – Common Object Request Broker
Architecture (CORBA). Эта архитектура служит для связи унаследован- ных систем, для интеграции систем, написанных на разных языках, и поддержки взаимодействия между компьютерами с различными аппа- ратными архитектурами. CORBA позволяет дать новую жизнь унасле- дованным системам и в то же время быстро интегрировать в них новые приложения, что обеспечивает предприятиям стратегические преиму- щества перед конкурентами, модифицирующими унаследованные сис-
300 темы. Еще один пример – свободно распространяемая интегрированная среда разработки Eclipse.
В целом процесс проектирования архитектуры состоит из система- тической декомпозиции элементов верхнего уровня на совокупности более мелких элементов. На рис. 6.12 исходный элемент путем деком- позиции разделяется на элементы «Модель», «Контроллеры» и «Пред- ставления». Каждый из них влияет на общее поведение исходного эле- мента.
Рис. 6.12. Декомпозиция как основа проектирования архитектуры любой программной системы
С помощью подхода ADD архитектор выбирает конкретную деком- позицию, стремясь улучшить определенные свойства конечного про- дукта. Следует, однако, иметь в виду, что каждая декомпозиция, как правило, какие-то свойства ухудшает. На рис. 6.12 декомпозиция «Мо- дель – Представление – Контроллер» (Model – View – Controller, MVC) выбрана для расширения возможностей модификации системы, в част- ности, для более эффективного добавления новых представлений моде- ли. Но такая декомпозиция приведет к снижению производительности, поскольку при возникновении любых изменений «Модели» придется уведомлять «Представление». С точки зрения архитектора, это прием- лемый компромисс, поскольку система работает не в реальном (компь- ютерном) времени, а в расчете на восприятие изменений человеком.
Процесс создания архитектуры предполагает разработку системы с конкретными свойствами и функциональностью, причем каждое из та- ких свойств имеет заданный приоритет. Начиная с общей структуры, которая поддерживает всю требуемую функциональность (она пред- ставлена в квадрате в левой части рис. 6.12), архитектор методично про- водит декомпозицию функциональности и распределяет ее между ком- понентами. Процесс декомпозиции, показанный на рис. 6.13, продолжа- ется до тех пор, пока компоненты не будут детализированы должным образом.
Рис. 6.13. Многоуровневая декомпозиция
301
Затем на предприятии могут быть созданы рабочие группы, каждая из которых станет заниматься проектированием и реализацией своего подмножества элементов архитектуры.
Как видим, суть процесса проектирования заключается в декомпози- ции системы независимо от способа ее представления: модульный, объ- ектный или компонентный. В любом случае результатом будет много- слойный программный продукт.
302
1 ... 23 24 25 26 27 28 29 30 ... 37