суббота, 13 ноября 2010 г.

Проектирование: расширение функциональной модели

Прежде чем приступать к проектированию структур данных, следует убедиться в том, что построенная функциональная модель системы достаточно полна.

Будем считать функциональную модель полной, если рассмотрение каждого последующего прецедента не приводит к добавлению новых функций.

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

Вернёмся к нашему примеру – "проектирование графического редактора для создания открыток".


В третьей части мы расширим функциональную модель модуля редактирования.


Для этого обратимся к видеоуроку "Как нарисовать открытку":


В этом уроке автор создаёт поздравительную открытку к Дню Защитника Отечества. Опишем последовательность действий автора в виде прецедентов.

Открытка состоит из четырёх основных элементов:

1)      пятиконечной звезды;
2)      щита;
3)      надписи;
4)      фона.

Поэтому первый прецедент будет выглядеть так:

Прецедент 1. Создать открытку

  1. Создать звезду.
  2. Создать щит.
  3. Создать надписи и расположить их на рисунке.
  4. Создать фон.

Этот вариант использования выглядит весьма лаконично. Он также противоречит определению, данному Алистером Коберном:

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

Алистер Коберн, Современные методы описания функциональных требований к системам/Пер. с англ. – М.: Издательство «Лори», 2002 г., с. 1.

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

Это сделано намеренно. По двум причинам.

Первая причина заключается в том, что наши варианты использования имеют конкретное предназначение – помочь проектировщику выявить функции системы.

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

Вторая причина заключается в том, что при указании участников проектировщику нужно будет распределить функции между ними.

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

Но вернёмся к нашей открытке...

А) Опишем процесс создания открытки в виде прецедентов.

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

Прецедент 2. Создать звезду

  1. Создать правильный пятиугольник.
  2. Преобразовать пятиугольник в звезду.
  3. Изменить размеры звезды.
  4. Окрасить звезду бронзовым цветом.
  5. Создать копию звезды.
  6. Изменить размеры копии звезды.
  7. Окрасить копию звезды жёлтым цветом.
  8. Изменить местоположение копии звезды.
  9. Объединить звезду и копию в группу.

Прецедент 3. Создать щит

  1. Создать контур щита.
  2. Создать каркас щита.
  3. Создать заклёпки.

Прецедент 4. Создать контур щита

  1. Создать прямоугольник.
  2. Преобразовать прямоугольник в многоугольник.
  3. Преобразовать стороны прямоугольника в кривые Безье.
  4. Склеить левую и нижнюю кривые.
  5. Изменить форму стороны склеенной кривой.
  6. Разбить верхнюю кривую на две кривых.
  7. Изменить форму левой кривой.
  8. Изменить форму правой кривой.
  9. Создать копию объекта.
  10. Сделать зеркальное отражение копии относительно вертикальной оси.
  11. Изменить местоположение копии.
  12. Создать фигуру с общим контуром для двух фигур.
  13. Склеить нижние кривые.
  14. Изменить форму нижней кривой.

Прецедент 5. Создать каркас щита

  1. Окрасить контур бронзовым цветом.
  2. Создать копию фигуры.
  3. Изменить размеры копии фигуры.
  4. Изменить местоположение копии фигуры.
  5. Окрасить нижнюю фигуру линейной градиентной заливкой.
  6. Окрасить верхнюю фигуру линейной градиентной заливкой.
  7. Убрать абрис с обоих фигур.
  8. Создать копию фигуры.
  9. Пропорционально изменить размер копии относительно центральной точки.
  10. Поместить копию на задний план.
  11. Изменить направление линейной градиентной заливки на протиивоположное.

Прецедент 6. Создать заклёпки

  1. Создать окружность.
  2. Окрасить окружность радиальной градиентной заливкой.
  3. Пропорционально изменить размеры окружности.
  4. Изменить местоположение окружности.
  5. Создать копию окружности.
  6. Изменить местоположение копии окружности.
  7. Повторить шаги 5 – 6 несколько раз.
  8. Объединить щиты и окружности в один объект.

Прецедент 7. Создать надписи и расположить их на рисунке

  1. Изменить местоположение звезды.
  2. Изменить местоположение щита.
  3. Изменить размеры звезды.
  4. Изменить размеры щита.
  5. Создать надпись "23".
  6. Создать надпись "февраля".
  7. Создать надпись "День защитника Отечества".
  8. Объединить надписи и рисунок в группу.

Прецедент 8. Создать надпись

  1. Создать текст.
  2. Установить выравнивание текста (по левому краю, по центру, по правому краю).
  3. Изменить размер шрифта.
  4. Изменить местоположение текста.
  5. Изменить размеры текста.
  6. Окрасить текст в чёрный цвет.
  7. Создать копию надписи.
  8. Окрасить копию в желтый цвет.
  9. Изменить местоположение копии.

Прецедент 9. Создать фон

  1. Создать элемент фонового рисунка.
  2. Сложить фоновый рисунок из элементов.
  3. Создать плашку.
  4. Сформировать изображение.
  5. Удалить лишние элементы.

Прецедент 10. Создать элемент фонового рисунка

  1. Создать треугольник.
  2. Создать копию треугольника.
  3. Пропорционально изменить размеры копии треугольника относительно центра фигуры.
  4. Изменить размеры копии треугольника по высоте относительно его верха.
  5. Изменить размеры копии треугольника по высоте относительно его низа.
  6. Окрасить треугольник радиальной градиентной заливкой..
  7. Окрасить копию радиальной градиентной заливкой.
  8. Убрать абрис с фигур.
  9. Объединить треугольники в группу.
  10. Создать копию фигуры.
  11. Зеркально отразить копию относительно горизонтальной оси.
  12. Изменить местоположение копии.
  13. Объединить объекты в один объект.

Прецедент 11. Сложить фоновый рисунок из элементов

  1. Создать копию элемента фона.
  2. Повернуть копию объекта на 5 градусов вокруг её центра.
  3. Выполнить шаги 1 – 2 36 раз.
  4. Поместить центры объектов в общую точку.
  5. Объединить объекты в один объект.

Прецедент 12. Создать плашку

  1. Создать прямоугольник.
  2. Окрасить прямоугольник радиальным градиентом.
  3. Поместить прямоугольник на задний план.

Прецедент 13. Сформировать изображение

  1. Поместить центры объектов "щит с надписями", "звезда", "фон" и "плашка" в общую точку.
  2. Объединить объекты в группу.

Прецедент 14. Удалить лишние элементы

  1. Создать прямоугольник.
  2. Изменить местоположение прямоугольника.
  3. Вычесть прямоугольник из рисунка.
  4. Выполнить шаги 1 – 3 4 раза (для каждой стороны открытки).
  5. Изменить местоположение фигуры.
  6. Изменить масштаб фигуры.

Б) Дополним нашу табличку, созданную в прошлый раз, названиями новых функций.

Отметим новые функции полужирным шрифтом.

Таблица: Функциональная модель модуля редактирования, версия 2

Группа
Функция
1. Создание
F1.1. Создать прямоугольник.
F1.2. Создать эллипс.
F1.3. Создать окружность.
F1.4. Создать прямую.
F1.5. Создать текст.
F1.6. Создать треугольник.
F1.7. Создать пятиугольник.
2. Копирование
F2.1. Создать копию фигуры.
3. Группирование
F3.1. Объединить фигуры в группу.
F3.2. Разделить группу на отдельные фигуры.
4. Размещение
F4.1. Переместить фигуру в заданную точку.
F4.2. Переместить фигуру на заданное расстояние.
F4.3. Поместить центры фигур в одну точку.
5. Масштабирование
F5.1. Изменить размеры фигуры по вертикали.
F5.2. Изменить размеры фигуры по горизонтали.
F5.3. Изменить размеры фигуры пропорционально.
F5.4. Изменить размеры фигуры пропорционально относительно центральной точки.
6. Размещение по Z
F6.1. Поместить фигуру на задний план.
F6.2. Поместить фигуру на передний план.
7. Форма
F7.1. Создать зеркальное отражение фигуры относительно вертикальной оси.
F7.2. Создать зеркальное отражение фигуры относительно горизонтальной оси.
F7.3. Изогнуть фигуру.
F7.4. Преобразовать эллипс/окружность в сектор.
F7.5. Изменить угол сектора.
F7.6. Преобразовать пятиугольник в звезду.
F7.7. Преобразовать прямоугольник в многоугольник.
F7.8. Преобразовать сегмент в кривую Безье.
F7.9. Изменить форму кривой (изогнуть кривую, сделать кривую выпуклой или вогнутой).
F7.10. Создать общий контур для нескольких фигур.
F7.11. Найти отсечение контура одной фигуры контуром другой фигуры.
F7.12. Разбить сегмент на две стороны.
F7.13. Разбить кривую на две кривых.
F7.14. Склеить соседние сегменты.
F7.15. Склеить соседние кривые.
F7.16. Склеить соседние сегмент и кривую.
8. Форматирование
F8.1. Изменить шрифт текста.
F8.2. Изменить размер шрифта.
F8.3. Изменить цвет текста.
F8.4. Установить выравнивание текста:
      - по левому краю;
      - по центру;
      - по правому краю.
9. Заливка
F9.1. Залить фигуру заданным цветом.
F9.2. Залить фигуру фрактальным рисунком.
F9.3. Залить фигуру линейной градиентной заливкой.
F9.4. Изменить направление линейной градиентной заливки на противоположное.
F9.5. Залить фигуру радиальной градиентной заливкой.
F9.6. Изменить направление радиальной градиентной заливки на противоположное.
10. Вращение
F10.1. Повернуть фигуру на 90 градусов.
F10.2. Повернуть фигуру на 180 градусов.
F10.3. Повернуть фигуру на произвольный угол.
11. Удаление
F11.1. Удалить фигуру.
F11.2. Удалить узел многоугольника (или кривой).
12. Абрис
F12.1. Удалить абрис.

4 комментария:

  1. Все изложение в этой части построено на двух моментах, о которых можно поспорить. Первый - что необязательно указывать действующих лиц (Actors), второй - до какого уровня детализировать прецеденты. Первый момент определяется тем, отталкивается ли ваш подход к проектированию от пользовательского интерфейса, или же от доменных объектов и бизнес-функций (в смысле, что из этого первично, а что вторично). Если первичен UI, то актеров придется указать. Ну, а с детализацией - это зависит... Я лично предпочитаю избегать глубокой детализации в функциональной спецификации, лучше добавить пару абзацев в тех.спец.

    ОтветитьУдалить
  2. 1) В данном примере (и во всех других примерах тоже) я отталкиваюсь от обязанностей системы, т.е. от бизнес-функций.

    GUI определяется обязанностями системы + техническими ограничениями.

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

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

    Спасибо,

    ОтветитьУдалить
  3. Да, для приведенного примера так и есть. Просто я чаще всего проектирую для веба, а там обычно отталкиваются от GUI mock-up для описания функциональности. То есть, типичный вид функ.спец. - структура сайта, и для каждой веб-страницы скриншот плюс текстовое описание действий/прецедентов.

    ОтветитьУдалить
  4. Игорь, а кто проектирует структуру сайта?

    ОтветитьУдалить