пятница, 19 августа 2011 г.

С чего начать проектирование программы? Часть 1


С чего начать проектирование программы? Классический объектно-ориентированный подход даёт нам однозначный ответ на этот вопрос: с выявления ключевых абстракций и построения объектной модели предметной области.

Джеймс Рамбо, один из создателей языка UML и Rational Unified Process'а, в своей книге "UML 2.0. Объектно-ориентированное моделирование и разработка" предлагает нам такой алгоритм проектирования:

  1. Изучить предметную область и выделить классы предметной области.
  2. Удалить лишние классы (несущественные или избыточные).
  3. Связать классы ассоциациями.
  4. Выделить в классах атрибуты.
  5. Реструктуризовать классы при помощи наследования.
  6. Добавить классы приложения.
  7. Добавить операции.

Дж. Рамбо, М. Блаха. UML 2.0. Объектно-ориентированное моделирование и разработка. 2-е изд. – СПб.: Питер, 2007, стр. 218 – 285.

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

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


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

Попытки подсмотреть архитектуру (а если выражаться точнее – конструкцию) программы в реальной жизни или в предметной области настолько же бесплодны, насколько бесплодно копирование крыльев птицы, навешивание их на руки человека и отправка последнего в полёт. Разработка новой техники идёт по противоположному пути: сначала разрабатывается теория функционирования устройства и лишь затем устройство реализуется "в металле".

Вернёмся к вопросу, вынесенному в заголовок. С чего начать проектирование программы?

Чтобы ответить на этот вопрос, сделаем небольшое отступление. Это отступление важно, потому что многие начинающие программисты о нём забывают. Его суть – любая техника разрабатывается для выполнения какой-либо полезной функции. Например, функция автомобиля – перемещение его владельца из пункта А в пункт Б. И программы здесь – не исключение. У каждой программы тоже должно быть определённое назначение, например, редактирование текста, редактирование таблиц или развлечение пользователя. Приступая к проектированию программы, разработчик должен чётко понимать её назначение.

Проектирование любой программы должно начинаться:

1)      с составления списка полезных функций, которые должна выполнять программа;
2)      с проектирования технологии реализации каждой полезной функции.

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

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

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

Рассмотрим предложенноый подход на примере. В качестве примера возьмём задачу про датчики и метеостанцию из книги Гради Буча и продемонстрируем, как можно подойти к решению данной задачи иным образом, чем это изложено у Г. Буча.

Требования к метеорологической станции
Система должна обеспечивать автоматический мониторинг следующих первичных погодных параметров:
  • скорость и направление ветра;
  • температура;
  • барометрическое давление;
  • влажность воздуха.
Система также должна вычислять некоторые производные параметры, в число которых входят:
  • коэффициент резкости погоды;
  • точка росы;
  • относительное изменение температуры;
  • относительное изменение барометрического давления.
В системе должна быть предусмотрена возможность определения текущего времени и даты, которые будут использоваться при генерации сообщении о максимальных и минимальных значениях первичных параметров за последние 24 часа.
Система должна обеспечивать постоянный вывод на дисплей текущих значений всех восьми первичных и производных параметров, а также текущее время и дату. Пользователь должен иметь возможность увидеть максимальные и минимальные значения любого из первичных параметров за 24 часа, сопровождаемые информацией о времени произведения соответствующего замера.
Система должна позволять пользователю проводить калибровку датчиков по известным опорным значениям, а также устанавливать текущие время и дату.
Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. – М.: "Издательство Бином", СПб: "Невский диалект", 1998 г., стр. 284, или: http://www.helloworld.ru/texts/comp/other/oop/ch08.htm

Начнём проектирование системы с описания процесса измерения и отображения температуры.

Первая диаграмма будет довольно простой:


На диаграмме показано, что температура считывается с датчика температуры напрямую и отображается на экране. Понятно, что это неверно. Скорее всего, датчик подключён к какому-нибудь порту, и его показания считываются программой через порт.

Внесём в диаграмму изменения:


В новой диаграмме тоже есть погрешность: данные на порт посылаются по определённому протоколу. Чтобы прочитать их, нужен модуль, который "понимает" этот протокол.

Внесём соответствующие изменения:


Сообщение от датчика температуры, скорее всего, закодировано в определённом формате (например, в формате json или в специализированном XML). Соответственно, потребуется парсер, который понимает этот формат:


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

Отобразим этап преобразования градусов на диаграмме:


Наконец, температуру нужно показать в определённом месте экрана (или в определённом окне).

Внесём изменения в схему:


Получилось достаточно подробное описание процесса измерения и отображения температуры.

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

В этом случае, диаграмма процесса будет выглядеть так:


Наряду с такими компонентами, как:

  • парсер атмосферного давления,
  • конвертер атмосферного давления (например, из кило-паскалей в мм. ртутного столба) и
  • окном для вывода давления,

- которые являются дубликатами аналогичных компонентов для температуры, появляется компонент "диспетчер", который определяет, от какого датчика пришло сообщение (от датчика температуры или датчика атмосферного давления) и направляет его соответствующему обработчику.

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

Приведём список классов и операций:

Port
Читает данные, пришедшие на порт.
Protocol
Читает данные с порта по определённому протоколу.
Dispatcher
Определяет, от какого датчика поступило сообщение, и пересылает его соответствующему обработчику.
Temperature Parser
Разбирает сообщение от датчика температуры.
Barometric Pressure Parser
Разбирает сообщение от датчика атмосферного давления.
Temperature Converter
Преобразует температуру из одних единиц в другие.
Barometric Pressure Converter
Преобразует атмосферное давление из одних единиц в другие.
Temperature Window
Отображает температуру в специальном окне.
Barometric Pressure Window
Отображает атмосферное давление в специальном окне.
Screen
Отображает окна на экране.


ЛИТЕРАТУРА:

1.      Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. – М.: "Издательство Бином", СПб: "Невский диалект", 1998 г. Или: http://www.helloworld.ru/texts/comp/other/oop/index.htm
4.      Рамбо Дж., Блаха М. UML 2.0. Объектно-ориентированное моделирование и разработка. 2-е изд./Пер. с англ. – СПб.: Питер, 2007. – 544 с.: ил.
5.      С.В. Сычев, К.А. Лебедев. Освобождение узников оператора IF - http://www.triz-ri.ru/themes/method/creative/creative57.asp


39 комментариев:

  1. Статья написана мутно и непонятно.

    ОтветитьУдалить
  2. 2 Анонимный: конкретизировать можете? Что непонятно? В какой части статьи непонятно?

    ОтветитьУдалить
  3. Да нормально написано, просто больше подходит людям с абстрактным складом ума в противовес с предметным.

    Хотя, может и вправду это будет непонятно, для тех кто прежде не сталкивался с методологиями проектирования.

    Мне раньше тоже было не очень понятно, какими способами обеспечивается полнота модели, да и вообще полнота требований.

    Интересный стиль - вспоминается советская литература 80-х годов))

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

    ОтветитьУдалить
  5. Диаграмма страдает избыточностью и я так понимаю, что диаграмма условная, а не по принципам UML, в противном случае мне не ясна жесткая связь классов.

    Не ясно зачем Temperature Window и Barometric Pressure Window. Не проще сразу передавать температуру через интерфейс на Screen?

    Temperature Converter и Temperature Parser стоило бы объединить в один класс.

    В общем хотелось бы посмотреть на итоговую диаграмму классов. :)

    ОтветитьУдалить
  6. >использование паттерна Behavior
    а можно чуть подробнее расскажать как его использовать в данном контексте?

    ОтветитьУдалить
  7. От Dispatcher передовать объект который будет содержать ParserBehavior->ConverterBehavior->DisplayBehavior. Процесс станент опять линейным. Процедура парсинга данных, их дальнейшей конвертации и создания данных для отображения (тут конечно я с блоком Pressure Windows не согласен, за это должны отвечать конкретные типы устройств, т.е клиенты) будут сконцентрированы в одном месте... и если потребуется их изсенить не придется лазить по разным местам. Dispatcher определяет, от какого датчика поступило сообщение и создает конкретный объект, у которого есть своя реализация поведения, и передает его уже дальше по линейной цепочке. А чтобы схема вообще на мой взгляд выглядела верно, то нужно еще ввести клиента для получения данных от его источника, потому как таких клиентов могут быть сотни, то неплохо было бы предусмотреть нагрузку на источник данных. Итого схема будет выглядеть следующим образом.

    ... Dispatcher -> Parser -> Converter -> DataProvider (паттерн service locator) client (он же Pressure Window) -> Screen

    ОтветитьУдалить
  8. Я что-то не помню ни какого Behavior, но могу примерно догадаться о чем идет речь. Вроде говорят о паттерне Наблюдатель.

    Речь идет о том, сенсоры ничего не знают о HUB. Они реализуют интерфейс с методом Update и через него производят оповещение всех своих подписчиков.

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

    ОтветитьУдалить
  9. Хочется все таки разобраться с Наблюдателем.
    Посмотрел:
    http://www.dofactory.com/Patterns/PatternObserver.aspx#_self2
    Как применить для данной ситуации?
    Кто будет Subject? кто Observer?

    ОтветитьУдалить
  10. 2 Анонимный: При чём тут отдельный паттерн - ведь описывается общая схема процесса? Паттерн - это отдельный фрагмент схемы или способ реализации этого фрагмента. Чтобы спроектировать систему, надо сначала представить себе общую схему, описать технологию, как программа работает, а не мыслить отдельными фрагментами.

    Что касается Вашего вопроса про несколько экранов, то схема ведь не финальная. Будет продолжение, и в новой статье я планировал затронуть похожую задачу.

    Относительно Вашего вопроса про дублирование элементов: Зачем объединять преобразователь Цельсий в Фаренгейты и Паскалей в миллиметры ртутного столба?

    ОтветитьУдалить
  11. > Temperature Converter и Temperature Parser стоило бы объединить в один класс.

    Сергей, из продолжения Вы увидите, что это нецелесообразно.

    ОтветитьУдалить
  12. To Аноним, который паттерном интересовался:
    На вашей диаграмме не полностью картина показана, не хватает наблюдаемого объекта. Суть шаблона в том, что есть интефейс, который реализуется в температурном сенсоре. Интерфейс позволяет подписаться/отписаться на событие и некий метод Update. Это то что не хватает на вашей диаграмме.

    На вашей диаграмме есть интерфейс Obsever, от которого наследуется конкретный наблюдатель. Это все понятно. А вот наблюдаймый объект хранит ссылки на конкретные Observer, через интерфейс Observer.

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

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

    ОтветитьУдалить
  13. askofen надеюсь вы правы, но почему-то мне кажется, что мы получим класс, который не имеет своего состояния и по функционалу соответствует простому методу.Я считаю, создавать классы-пустышки, которые не изменяют состояние данных - не разумное захламление схемы.

    Хотя...кто знает...жду продолжения

    ОтветитьУдалить
  14. 2 Сергей: Класс - здесь условное название. Под ним понимается компонент, который выполняет определённые обязанности. Если вместо класса лучше написать функцию, то лучше написать функцию. ))) Конкретные решения принимаются при проектировании реализации.

    ОтветитьУдалить
  15. 2 Анонимный: Вы предугадали тему следующий статьи. Понятно, что нужен промежуточный объект для складирования данных. У Вас это - DataProvider.

    ОтветитьУдалить
  16. Относительно Вашего вопроса про дублирование элементов: Зачем объединять преобразователь Цельсий в Фаренгейты и Паскалей в миллиметры ртутного столба?
    Так на то он и преобразователь... на вход подаешь одно значение, а на выход другое..... То как будет реализовывыаться преобразование, отвечает конкретный преобразователь, а процесс остается линейным, и нет ветвления на две ветки с похожей логикой но разной реализацией, есть просто объект который умеет принимать на вход данные и парсит их в нужный формат, и так же при необходимости может преобразовывать эти данные в другой формат, ветвление на ветки происходит только на момент создания конкретного объекта, а дальше просто идет линейная логика, которая будет вызывать методы этого объекта.

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

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

    ОтветитьУдалить
  18. Вы оба спорите о разном. Аноним - автор нарисовал черновой вариант схемы, без конкретики. Жди диаграмму классов, тогда там уже и будешь претензии автору слать. =)

    Автор, на мой взгляд, все-таки не до конца понимает построение схемы, но пока не будем строго судить.

    ОтветитьУдалить
  19. 2 Сергей: Какую схему я на Ваш взгляд не понимаю?

    ОтветитьУдалить
  20. А так - да, моей целью было показать метод, а не описать архитектуру в финальном качестве в одной статье.

    ОтветитьУдалить
  21. Стрелочки что на диаграмме обозначают? Dataflow? Это неинтересно, для подавляющего большинства программ dataflow будет (входные данные -> модуль1 -> модуль2 ->...-> модульN -> выходные данные).

    Гораздо интереснее стрелочками рисовать кто кого вызывает, надо будет конечно уточнить протоколы работы датчиков и способ вывода информации на UI.

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

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

    ОтветитьУдалить
  22. По поводу цитируемой книги. Рамбо и Блаха дают реомендации для построения диаграммы классов вообще. А в целом они излагают свой подход в ракусрсе трех точек зрения: взаимодействие, структура, поведение-изменение состояния.
    При этом они говорят об этапах
    1. анализ предметной области - который в ООП часто начинается именно спостроения domain model - какую информацию нужно хранить и как ее обрабаотывать
    2. анализ приложения - суть которого понять видимые части системы, через ее назначение и модели предметной области. на это стадии выделяются интрефейсы - каким образом система взаимодействует с окружением и как примерно решает задачи окружения

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

    ОтветитьУдалить
  23. @Ключевая ошибка теоретиков объектно-ориентированного подхода заключается в непонимании различий между описательными и процедурными моделями. Описательные модели с той или иной степенью точности описывают внешние проявления явления без понимания его внутренних механизмов, причинно-следственной связи, без предоставления технологии его воспроизведения.@

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

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

    ОтветитьУдалить
  25. Эдуард. Рамбо и Блаха рекомендуют использовать модель классов, полученных при анализе предметной области, в виде структур данных приложения. Они так и пишут: "Цель этапа проектирования классов состоит в том, чтобы довести определения классов и ассоциаций до их конечного вида и выбрать алгоритмы для операций" (стр. 323). В этом и заключается ошибка: они пытаются организовать архитектуру программы на базе конструкций реального мира (или предметной области).

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

    На мой взгляд, данное утверждение содержит ошибку и неправду. Ошибка заключается в пренебрежительном отношении к функциональности. Любая система проектируется и создается для выполнения полезных функций. А неправда заключается в том, что объектно-ориентированная система оказывается более жизнеспособной при изменениях. Мой опыт участия в порядка 30 проектах разной степени сложности свидетельствует, что это не так.

    ОтветитьУдалить
  27. Относительно непонятности причинно-следственных связей. Там, где непонятно, я готов прояснять.

    ОтветитьУдалить
  28. Кирилл, спасибо за ответ. По поводу цитаты на странице 42. Я с Вами согласен, утверждение читается слишком странным. Но тут нужен полный контекст и учесть тот факт, что это перевод с английского.
    насчет ошибки - ну трудно сказать. что это ошибка.
    насчет неправды - соглашусь, но отчасти. Разве процедурно ориентированные системы более жизнеспособны? Тут еще следует понять что авторы имел в виду под жизнеспособностью при возможных изменениях :)

    ОтветитьУдалить
  29. Проблема не в использовании классов и объектов. Наоборот, на мой взгляд, они лучше помогают структурировать код. Проблема заключается в том, что положено в основу классификации. Если в основу положен какой-нибудь объект реального мира или предметной области, и разработчик пытается структурировать код на этом основании, то, как правило, ничего не получится. Наглядный пример этого можно посмотреть здесь (http://www.triz-ri.ru/themes/method/creative/creative52.asp).

    ОтветитьУдалить
  30. Я почитал несколько статей Альтшуллера. Теперь основания Ваших рассуждений мне более понятны. Хотя есть какой-то момент, который мешает мне принять Вашу точку зрения безоговорочно. Но что за момент понять не могу пока:)

    ОтветитьУдалить
  31. Кстати, Кирилл, по поводу цитаты в топе статьи. На указанных страницах представлен Анализ предметной области.
    И первый абзац главы определяет цель данного этапа разработки. Отбросив шелуху, можно сказать - цель (задача) этапа представить однозначное, формализованное описание требований к системе в виде аналитической модели.

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

    Тем не менее вопросы проектирования системы, т.е. архитектуры, и классов идут дальше как отдельная глава. И процесс проектирования выглядит несколько иначе, чем вы описали.

    ОтветитьУдалить
  32. Эдуард, мне кажется, что книга Рамбо, в особенности, пример с банкоматом, заслуживает отдельного обсуждения.

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

    Если посмотреть на эту модель с точки зрения программиста, который должен реализовать классы в коде, то у него возникает масса вопросов, например:

    1) Зачем ему большинство классов из этой модели: Bank, Consortium, Customer, CardAuthorization, RemoteReceipt и т.д.?

    2) Кто в этой модели отвечает за отправку сообщений банку или консорциуму?

    3) Кто решает, следует ли отправить сообщение напрямую в банк, или в консорциум?

    4) Как будут выглядеть сообщения на разные операции: верификация карты, запрос остатка, запрос выписки по счету, запрос на списание и выдачу средств, запрос на пополнение счета внесенной наличностью и т.д.? Какие поля они будут содержать?

    5) С учётом, что операции асинхронны, то кто будет ждать ответа на сообщения? Какие будут варианты ответов? Каков протокол взаимодействия банкомата с банком или консорциумом?

    6) Кто отвечает за безопасность передаваемых данных? Кто будет шифровать и дешифровать сообщения?

    7) И т.д.

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

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

    Замечу в Вашей архитектуре тоже нет ответов, на большую часть вопросов которые вы задали (ну если убрать моменты предметной области).

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

    ОтветитьУдалить
  34. Эдуард, я прекрасно понимаю, что в одной книге или статье не описать развёрнуто и подробно пример проектирования серьезного приложения.

    Но я написал не о полноте описания архитектуры, а о том, что из приведенных Рамбо классов невозможно сложить функцию. Классы и объекты есть, а вот как они взаимодействуют для достижения цели (например, для выполнения функции банкомата "авторизация клиента") - нет.

    Хотя бы одну функцию описать было можно.

    ОтветитьУдалить
  35. Кирилл, согласен с Вами. Вообще внимательное прочтение книг амигос, вызывает у меня скептическое отношение к столь сиятельному триумвирату. Правда книга Блахо и Рамбо скорее ориентирована на UML.

    Вы читали книгу UML2 и унифицированный подход (http://forcoder.ru/uml/uml-2-i-unificirovannyj-process-prakticheskij-obektno-orientirovannyj-analiz-i-proektirovanie-914). Она мне показалась более внятной.

    Вообще я начинал изучать ООП с Дж. Шмуллера и Лармана. А поскольку перед этим мне пришлось изучить и даже преподавать SADT Дугласа и ДеМарко, + погружение в теорию систем и системный анализ, у меня как-то не случилось функционального разрыва, скорее сложно было въезжать в объектную парадигму

    ОтветитьУдалить
  36. Хотя Вы знаете, 13 глава несколько схематично, но вообще-то содержит описание функций: сценарии вариантов использования - это процесс взаимодействия, есть диаграммы последовательности (правда зачаточные), есть коммуникационные диаграммы с потоком работ-функций, ну есть конечный автомат -довольно прилично надо сказать

    ОтветитьУдалить
  37. Эдуард, насколько я понял предысторию трех амигос, то изначально у каждого из них был свой подход. Когда они объединились, то первоначальной целью было создать единую методику объектно-ориентированного проектирования. Но впоследствии амигос отказались от этой цели и заменили её другой целью - созданием графической нотации. В результате, нотация, на мой взгляд, удалась, а методика - так и не была создана.

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

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