суббота, 29 июня 2013 г.

Я примерно понял - почему МНОГИМ программистам на Delphi не нужен UML

Доводя до "абсурда" - примерно так. Давайте всё запихнём в BD. Бизнес-логику впихнём в хранимые процедуры. Максимум что нужно - это Er-Win или его аналоги. И то - ДАЛЕКО не всегда...

А Delphi и код на нём - "ну что Delphi"... Там же "формочки".  Ну зачем там UML?

А там где SQL - "не ложится" - всё равно - ВПИХНЁМ SQL... ClientDataSet или MemTable.

"Выливаем воду из чайника"... А дальше - по накатанной...

Или я чего-то не понимаю?

Меня лично только удивляет ОДНО - как гиганты типа Apple, MS или IBM без UML и КОДОГЕНЕРАЦИИ - живут? Я вот лично - НЕ МОГУ.. А у них проекты - ПОБОЛЬШЕ моих будут наверное... Или они это ВСЁ ТЩАТЕЛЬНО скрывают?! Или БЕРУТ ЧИСЛОМ?

А как же тогда "мифический человеко-месяц"?

Или всё таки 9 женщин (или 99) могут родить ребёнка за месяц?

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

  1. NameRec:
    «Меня лично только удивляет ОДНО - как гиганты типа Apple, MS или IBM без UML и КОДОГЕНЕРАЦИИ - живут? Я вот лично - НЕ МОГУ..»
    -- Но ведь это же не значит, что без кодогенерации невозможно создавать большие системы? Так ведь? :-)

    «Или они это ВСЁ ТЩАТЕЛЬНО скрывают?!»
    -- Вряд-ли... :-)

    «Или БЕРУТ ЧИСЛОМ?»
    -- Ну почему обязательно числом... :-)
    Есть много разных подходов к разработке, и для меня пока не факт, что подход, основанный на кодогенерации - самый эффективный.

    Меня пока смущают затраты на поддержание инфраструктуры, в которой диаграммы UML являются *источником* кода.
    Хорошо конечно, когда есть простая и понятная диаграмма (или связанная их совокупность), от которой можно немедленно перейти к коду и наоборот. Мне было бы интересно, как выглядит инфраструктура, в которой это - нормальное явление.
    С другой стороны, не чувствую себя стеснённым отсутствием диаграмм в случае, если есть качественный код с комментариями.

    ОтветитьУдалить
    Ответы
    1. "Но ведь это же не значит, что без кодогенерации невозможно создавать большие системы? Так ведь? "

      Так вот я и удивляюсь - КАК?

      Удалить
    2. "Меня пока смущают затраты на поддержание инфраструктуры, в которой диаграммы UML являются *источником* кода.
      Хорошо конечно, когда есть простая и понятная диаграмма (или связанная их совокупность), от которой можно немедленно перейти к коду и наоборот. Мне было бы интересно, как выглядит инфраструктура, в которой это - нормальное явление.
      С другой стороны, не чувствую себя стеснённым отсутствием диаграмм в случае, если есть качественный код с комментариями."

      -- я пытался и код структурировать и комментарии писать. Всё равно - "за деревьями леса не видать". А модель - реально помогает. Ну - МНЕ ЛИЧНО.

      Удалить
    3. "Меня пока смущают затраты на поддержание инфраструктуры, в которой диаграммы UML являются *источником* кода."

      -- по мне - затраты - РАЗОВЫЕ. На внедрение технологии. Дальше - одни плюсы. Опять же - ДЛЯ МЕНЯ ЛИЧНО.

      Удалить
    4. "Есть много разных подходов к разработке, и для меня пока не факт, что подход, основанный на кодогенерации - самый эффективный."

      Можете поделиться - какие подходы вы имеете в виду? Ну "на пальцах", или ссылки на интернет?

      Удалить
    5. NameRec:
      «Так вот я и удивляюсь - КАК?»
      -- А что Вас смущает? Какие задачи Вам представляются "неразрешимыми" или разрешимыми с большим трудом?

      «я пытался и код структурировать и комментарии писать. Всё равно - "за деревьями леса не видать"»
      -- Что Вы имеете ввиду, когда говорите "за деревьями леса не видать"?
      Документированные интерфейсы классов, примеры использования, документы, которые описывают архитектуру решений (с UML кстати, но без детализации) очень неплохо проливают свет. Тесты те же, из них можно многое почерпнуть.
      Кроме того, известен принцип "чёрного ящика" - если стремиться к тому, чтобы его использование не вызывало проблем, знание внутреннего устройства (чему способствует UML) не будет так уж часто востребованным.
      Ну, можно взять даже Ваш пример с контейнерами. Достаточно развёрнутого примера использования, например, в настоящем приложении, для того, чтобы получить представление о том, как *это* следует применять. Если дойдёт до рефакторинга самой поддержки этих классов, то их реализация по простоте конкурирует с соответствующими диаграммами UML :-)
      Правда, для полноценного понимания Вашей реализации требуется ещё знать о "хоккее" с include-файлами, признаться, для меня этот фокус оказался несколько м-м-м... непривычен, скажем так.

      «"Меня пока смущают затраты на поддержание инфраструктуры, в которой диаграммы UML являются *источником* кода."
      -- по мне - затраты - РАЗОВЫЕ. На внедрение технологии. Дальше - одни плюсы. Опять же - ДЛЯ МЕНЯ ЛИЧНО.»
      -- Ну-ну :-) Думаю, не всё так просто...
      Сначала нужна *разработка* этой технологии. В частности, инструмент для создания диаграмм, увязка кода с ними, кодогенерация. Это всё - вложения в инфраструктуру. И совсем немалые вложения!
      Что мы получим на выходе? - Ну... Как минимум, более высокий порог входа, поскольку потребуется обучить неофитов новой схеме работы, когда UML - на первом месте и является источником всего.
      Далее, к недостаткам UML я относил быстрое усложнение диаграмм по мере детализации описания задачи. Выше я отметил, что реализация соответствующих контейнеров сравнима по сложности с соответствующими UML-диаграммами. А ведь речь идёт об очень простых классах.
      Возможно, это дело привычки, но я не могу избавиться от ощущения, что UML здесь - лишнее звено. Но обращаю внимание - это только ощущение, я ведь стал изучать Ваш блог, в частности потому, что хотел бы убедиться в обратном.

      «"Есть много разных подходов к разработке, и для меня пока не факт, что подход, основанный на кодогенерации - самый эффективный."
      Можете поделиться - какие подходы вы имеете в виду? Ну "на пальцах", или ссылки на интернет?»
      -- Ну, кое-что я обозначил выше. Под подходами я понимал семейство методов Agile-CANBAN.
      Но это, скорее, касается процессов.
      Можно и "на пальцах", но мне хотелось бы сначала определиться с тем, о чём именно мы будем говорить, о тех проблемах, которые с Вашей точки зрения решает UML и, решение которых без него, с Вашей точки зрения, представляет значительную сложность.

      Удалить
    6. Всё правильно кстати говорите :-)
      И вы - не первый кто это говорит.

      Тесты - кстати - да. Они есть. И они решают задачу. В частности задачу "документирования". Я кстати специально в примерах - тесты привожу. Пусть и "надуманные".

      Что касается трудозатрат - вы ПРАВЫ. Если речь про ОТДЕЛЬНУЮ организацию и НОВУЮ технологию.

      Но НЕОФИТОВ - вы - ЧЕРТОВСКИ ПРАВЫ! Просто - в ТОЧКУ!

      НО! Собственно поэтому я это всё и пишу в ПУБЛИЧНОМ доступе. У нас ВНУТРИ - "уже многое сделано".

      НО! Собственно и хочется - ПОДЕЛИТЬСЯ соображениями. Так сказать "неким иным взглядом на проектирование и UML в частности". Вдруг - зерно упадёт на благодатную почву. Я ведь сам - НИЧЕГО не придумал - только черпал ЧУЖИЕ идеи. Может быть и тут кто-то почерпнёт и ПРОНИКНЕТСЯ. И СДЕЛАЕТ что-то качественно НОВОЕ.

      Что касается Agile - то тут по-моему - "несколько из другой оперы". Оно позволяет "организовать процесс", но ИМХО не решает "структурные проблемы кода".

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

      А вот ТУТ - у меня - ЕСТЬ РЕЦЕПТЫ. Я их постараюсь описать.

      Удалить
    8. "признаться, для меня этот фокус оказался несколько м-м-м... непривычен, скажем так."

      -- согласитесь - ХОРОШИЙ "фокус", а? :-)

      Жаль я ещё до контейнеров ЛЮБЫХ типов не добрался (например строк и записей). Но там по-моему и так - всё уже на поверхности. Доберусь со временем.

      Удалить
    9. "Правда, для полноценного понимания Вашей реализации требуется ещё знать о "хоккее" с include-файлами"

      Так вот этот "хоккей" как раз и упаковывается в UML и генерацию :-)

      Удалить
    10. "А ведь речь идёт об очень простых классах."

      Так вот дело-то как раз в том, что СЛОЖНЫЕ классы на UML делаются НЕ СЛОЖНЕЕ контейнеров. В том-то и штука. Логарифмирование сложности.

      Я просто примеры ещё не привёл. Сложно примеры приводить. Из реальной системы - нельзя. А "придумывать" - чтобы было понятно - сложно.

      Потому и начал немного про "MVC" писать. Хотя там совсем не про MVC.

      Удалить
    11. NameRec:

      «"Далее, к недостаткам UML я относил быстрое усложнение диаграмм по мере детализации описания задачи."
      А вот ТУТ - у меня - ЕСТЬ РЕЦЕПТЫ. Я их постараюсь описать.»
      -- Могу предположить, что Вы имеете ввиду иерархичность диаграмм, на которую Вы указывали в одном из своих постов, когда предложили заглянуть в один из "квадратиков".
      Но рецепты - безусловно представляют большой интерес.

      «"признаться, для меня этот фокус оказался несколько м-м-м... непривычен, скажем так."
      согласитесь - ХОРОШИЙ "фокус", а? :-)»
      -- Ну... :-) Мне пока трудно судить. Восприятие фокуса не должно быть оторвано от контекста его проявления. О контексте же я пока имею недостаточное представление.
      Что же касается самой идеи примесей (mixin)... Меня немного смутило вначале, почему я не испытывал в них необходимости. Но потом - стало понятно :-)

      «"Правда, для полноценного понимания Вашей реализации требуется ещё знать о "хоккее" с include-файлами"
      Так вот этот "хоккей" как раз и упаковывается в UML и генерацию :-)»
      -- Как я понимаю, без "шаблонных решений" такая упаковка будет затруднительной. Я ошибаюсь?

      «"А ведь речь идёт об очень простых классах."
      Так вот дело-то как раз в том, что СЛОЖНЫЕ классы на UML делаются НЕ СЛОЖНЕЕ контейнеров. В том-то и штука. Логарифмирование сложности.»
      -- Если под сложными классами мы понимаем одно и то же, т.е. сложный класс отличается от простого тем, что в нём присутствуют ассоциации с другими классами, зависимости, композиция и агрегация, то
      у меня сложилось ощущение, что одно из двух:
      * Либо для сложных классов *необходимо* шаблонное решение, специализирующее детали трансляции отношений в код
      * Либо у вас проработан набор обобщений такой специализации и вы используете такие обобщения на диаграммах сложных классов, обеспечивая повторное использование шаблонов.
      Я правильно понял идею?

      Удалить
    12. "Меня немного смутило вначале, почему я не испытывал в них необходимости. Но потом - стало понятно :-)"

      И почему? :-)

      Удалить
    13. "Я правильно понял идею?"

      Правильно.

      Удалить
    14. "Как я понимаю, без "шаблонных решений" такая упаковка будет затруднительной. Я ошибаюсь?"

      Вот тут - не понял вопроса :-(

      Удалить
    15. "Могу предположить, что Вы имеете ввиду иерархичность диаграмм, на которую Вы указывали в одном из своих постов, когда предложили заглянуть в один из "квадратиков""

      Отчасти - да.

      Удалить
    16. «"Меня немного смутило вначале, почему я не испытывал в них необходимости. Но потом - стало понятно :-)"
      И почему? :-)»
      -- Очень в двух словах.
      1. Если не ошибаюсь, в одном из постов Вы обращали внимание на то, что делегирование реализации интерфейса очень похоже на использование примесей. Это первое обстоятельство.
      2. Известные мне случаи, когда примеси были бы уместны, были вызваны особенностями выбранной архитектуры в унаследованном коде.
      Например, в VCL отсутствует интерфейс IDataSet, соответственно TDataSource.DataSet имеет тип класса TDataSet, а не интерфейса IDataSet.
      В результате отсутствует простая возможность сделать свой класс-потомок (в терминах шаблонов проектирования - декоратор), например, TComponent, поддержать в нём интерфейс IDataSet, делегировав его какому-нибудь объекту-адаптеру и, в итоге, обеспечить прозрачное использование его в качестве набора набора данных для, скажем, DBGrid.
      Вместо этого можно "примешать" свою функциональность к конкретной реализации набора данных, но совершенно понятно, что это менее гибко, чем я обозначил в предыдущем абзаце.
      Для чего это нужно? - Иногда, решая архитектурные задачи, может потребоваться обеспечить общее поведение для *всех* без исключения наборов данных в определённом контексте. Например, в какой-либо форме, или в рамках какого-либо соединения с БД. Утрированный пример: при определённых условиях обеспечить протоколирование всех операций записи в таблицы *данного* соединения.
      Это удобно сделать, если посредством агрегации "завернуть" конкретный набор данных (TIBDataSet или клиент TClientDataSet) в другой класс, обладающий интерфейсом TDataSet.
      К сожалению, по изложенным в начале этого пункта причинам, такое решение в настоящий момент оказывается трудоёмким настолько, что приходится искать обходные пути.
      Вместе с тем, хочу обратить внимание, что это обусловлено исключительно архитектурными особенностями платформы и нежелание испытывать высокие риски по её рефакторингу.
      Но в остальных случаях мы прибегаем к такому рефакторингу, соответственно, и необходимость в примесях отпадает.
      3. Известно, что поскольку примеси являются утрированным вариантом множественного наследования, в языках, которые поддерживают такое наследование, примеси выражаются очень естественно.
      Разумеется, это же касается практически всех скрипт-языков, причём независимо от поддержки в них множественного наследования, а просто в силу их динамической природы.
      Опуская множество технических деталей скажу, что если выразить понятие "метод" через более общее понятие "событие", поддержать рассылку событий на самом нижнем уровне (TObject - идеальное место, но это невозможно. Поэтому, соответствующую поддержку можно разместить в его прямом потомке и, разумеется унаследовать все классы от него) то появится возможность не использовать примеси явно, обеспечивая большую функциональность.

      Мнда... Не уверен, что всё из сказанного мною будет понятно, но нужно же с чего-то начать... ;-)

      Удалить
    17. «««"Правда, для полноценного понимания Вашей реализации требуется ещё знать о "хоккее" с include-файлами"
      Так вот этот "хоккей" как раз и упаковывается в UML и генерацию :-)»
      -- Как я понимаю, без "шаблонных решений" такая упаковка будет затруднительной. Я ошибаюсь?»
      -- Вот тут - не понял вопроса :-(»
      -- Я к тому, что UML указывает на наличие связи между классами и на вид этой связи (зависимость, агрегация и т.п.), но не содержит информации о способе реализации (средствами конечного языка программирования) этой связи.
      У меня сложилось впечатление, что шаблонное решение как раз и содержит *реализацию* этих связей на конечном языке программирования.
      Вы упомянули об "упаковке" техники с include-файлами в "UML и генерацию" (кода). Мне показалось, что эта упаковка производится на уровне шаблонного решения.
      Я не ошибаюсь?

      Удалить
    18. Это всё конечно ЗДОРОВО написано, но не про примеси - вообще :-(

      Удалить
    19. "Вы упомянули об "упаковке" техники с include-файлами в "UML и генерацию" (кода). Мне показалось, что эта упаковка производится на уровне шаблонного решения.
      Я не ошибаюсь?"

      Не ошибаетесь. На термин СТЕРЕОТИП только обратите внимание.

      Удалить
    20. «Это всё конечно ЗДОРОВО написано, но не про примеси - вообще :-(»
      -- Честно говоря, я Вас не понял.

      Удалить
  2. NameRec:

    «Что касается Agile - то тут по-моему - "несколько из другой оперы". Оно позволяет "организовать процесс", но ИМХО не решает "структурные проблемы кода".»
    -- Да, само по себе - не решает :-)
    Про Agile-разработку я упомянул в связи с тем, что в её среде UML имеет ограниченное хождение.
    Есть тезис, высказанный одним из классиков "Код - и есть дизайн". Этим подчёркивается, что код и есть конечное отражение архитектуры и для составления представления о ней следует анализировать именно его. Здесь очевидное противопоставление UML, тем интереснее для меня ваша методология.
    Что касается собственно "структурных проблем кода", то здесь я могу тезисно обозначить следующий комплекс мер.
    Классы можно отнести к двум категориям: архитектурные (форма, фрейм, источник, набор данных и т.п.) и технические - например, реализация поведения конкретной формы или фрейма.
    Разнообразие архитектурных классов ограничивается и документируется. На самом деле документировать требуется только свои, т.е. нестандартные архитектурные классы, которых не должно быть много.
    В качестве документации может выступать интерфейсная часть модуля.
    Далее, вводится понятие уровня программной поддержки и описывается (можно и в UML) структура этих уровней (1. Core → 2. (VCL, DB, ThirdParty) → 3. (Common, Oracle, FB, Multi-Tier)). Более высокий куровень может ссылаться на более низкий, но не наоборот.
    Архитектурные классы расположены на всех этих уровнях.
    Далее идёт уровень приложения, который содержит исключительно технические классы, которые могут строить экземпляры архитектурных или таких же технических.
    Вводится понятие семейства для технических классов, в сущности, среди таковых можно выделить также две категории: обработчики архитектурных и самостоятельные классы, служащие утилитарным целям.
    Дополнительно описываются правила подключения функциональности к приложению (в сущности, обработчиков архитектурных классов). Они довольно просты.
    Что достигается: для решения подавляющего числа задач «видеть весь лес» совершенно ненужно, достаточно «видеть те совокупности деревьев», среди (и посредством) которых должно быть «выращено» решение.
    Это в очень общих словах, максимум, что позволяет формат комментариев.

    ОтветитьУдалить
    Ответы
    1. Всё правильно пишете.

      Слои... Слои - это главное.

      Но это и есть "необходимость договариваться".

      Удалить
    2. "«выращено» решение"

      Хорошая метафора :-)

      Удалить