Теория и практика использования диаграмм классов(Прочитано 56022 раз)
Господа!
Классы и объекты придумали умные люди. Умные потому, что они не усложняют суть, а упрощают, ибо ... (много поговорок). Меня всегда нервировали профессора коллапсирующие в своём океане информации. Всё гениальное должно быть до безобразия простым. Вот возьмём класс-объект, это гениальный бинарный примитив способный наиболее просто смоделировать сложнейшие процессы во вселенной. В отличие от реального мира схема класс-объект всегда положительна, а в жизни у примитивов есть и анти примитив. Почему физики умнее ИТ-шников? Они уже давно знают, но молчат ))
Я ИТ-шник. Смесь сетевика и программиста. И я призываю Вас своих коллег не коллапсировать, а упрощать и сбрасывать лишнюю массу для исключения коллапса.
Пархайте как бабочки, жальте как пчёлы!



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

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

Ах да...всерьез рассматривать разницу между типом и классом не стоит. Исторически типы появились для контроля корректности программ, и сокращения числа необходимых мнемоник операций над обьектами.
Классы появились когда стало понятно, что необходимо создавать сложные типы обьектов и иметь возможность все операции и инварианты обьекта описывать как нечто целостное. Тут и появился класс. Соббсно.
Наследование появилось как идея описания иерархических отношений родства на системе классов, и описании общих свойств обьектов.
Ну и так далее..
Из своего опыта могу сказать, что мне приходилось использовать розу для реализации сложных систем из сотен классов на С++, но разумеется безо всяких там отношений ассоциации, и проч. аналитической муры, а расписывая лишь пакеты классов с точными именами полей класса, прямыми описаниями методов, конструкторов и так далее. роза при генерации кода помогала с помошью параметров генерации создавать автоматически некий код(что было лень писать ручками), автоматически делать нужные инклуды, оформлять заголовки файлов и так далее.
Очень сомнительно, что применяя ассоциации, агрегирования и проч, можно проделать такую же работу за приемлемое время. диаграммы точно станут нечитаемыми в силу могучего изобилия стрелок, линий и проч.
Фактически использовались мной лишь отношения наследования и зависимости. А также средства разбрасывания класов по пакетам - файлам .сpp и .h в терминах с++.



добавление. топикстартер подходит к диаграмме классов с точки зрения чисто схематического и поверхностного моделирования некоей программной системы. я глубоко убежден, что такие диаграммы имеются в умл именно для решения задачи разработки программного обеспечения в терминах ооп и ничего другого.
Но! Всерьез ассоциациями и проч. архианалитикой ничего не опишешь. Если у вас классов 500, в каждом технически методов по 10, и собственных полей в среднем штуки 4 - вы в стрелочках просто запутаетесь.
А при таком обилии классов требуется именно наглядность представления, для работы с этой системой классов при ее коррекции или сопровождении.
Потому просьба на примеры из руководств типа на диаграмме три класса - клиент, продавец и заказ, и все на отношениях, не смотреть. они если и научны, то антипрактичны.



Alys, спасибо за интерес к теме и полезные высказывания. Правда они несколько запоздали. Тема была начата более полутра лет. За это время ситуация значительно прояснилась и понимание тоже

А при таком обилии классов требуется именно наглядность представления, для работы с этой системой классов при ее коррекции или сопровождении.
Не до конца понял Вашу мысль о наглядности представления



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



То что обьект может принадлежать к нескольким классам сразу - это могучая дурь, поскольку точный, актуальный тип обьекта задается его конструктором.
на данном этапе возможностей ООЯ, наверное, это действительно так, но почему же "могучая дурь"? Множественная классификация и множественное наследование в реальном мире встречается довольно часто, другое дело, что современный ООЯ просто не позволяет просто воспользоваться этим. Возможно пока в этом и нет потребности и есть гораздо более простые средства выразить это в программе.

Цитировать
Никто не мешает насиловать ооп концепцию и изменять ее до неузнаваемости. Ну например создать такую систему в которой тип обьекта может меняться. Вопрос только - какую концептуальную задачу мы этим решим и к чему такие фичи в вашем подходе.
а параметризированные классы не укладываются в то, что Вы описали?
Цитировать
Из своего опыта могу сказать, что мне приходилось использовать розу для реализации сложных систем из сотен классов на С++, но разумеется безо всяких там отношений ассоциации, и проч. аналитической муры,
Т.е. Вы считаете ассоциации - простой аналитической дурью?
А что вы понимаете здесь под "розой"

Цитировать
роза при генерации кода помогала с помошью параметров генерации создавать автоматически некий код(что было лень писать ручками), автоматически делать нужные инклуды, оформлять заголовки файлов и так далее.
Т.е. единственная причина использовать автогенерацию - это лень?

Цитировать
Очень сомнительно, что применяя ассоциации, агрегирования и проч, можно проделать такую же работу за приемлемое время. диаграммы точно станут нечитаемыми в силу могучего изобилия стрелок, линий и проч.
Трудно не согласиться, но не стоит ли все-таки различать аналитическую работу и собственно реализацию. Или Вы полагаете, что аналитика - суть пиар и ничего более?

Цитировать
Фактически использовались мной лишь отношения наследования и зависимости. А также средства разбрасывания класов по пакетам - файлам .сpp и .h в терминах с++.
Но Вы использовали это не потому ли, что это было полезно и сокращало время и позволяла не потеряться в массе информации?

Но! Всерьез ассоциациями и проч. архианалитикой ничего не опишешь. Если у вас классов 500, в каждом технически методов по 10, и собственных полей в среднем штуки 4 - вы в стрелочках просто запутаетесь.
Может быть все дело в точке зрения? Что такое эти 500 классов - откуда они появились? Это классы предметной области? Или уже объекты программной реализации? Все ли 500 классов вам нужны для анализа одновременно? Не разбиваются ли эти 500 классов на смысловые группы, которые и следует рассматривать отдельно? Разве проектировщики баз данных отказываются от представления связей только из-за того, что их слишком много? Повторяюсь не следует ли всегда при решени задачи держать в голове: (1) точку зрения, (2) контекст использования, (3) уровень использования ?

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

Цитировать
однако в данном случае стоит акцентровать. имелось ввиду, что диаграмма не перенасыщена отношениями аггрегирования и проч. ассоциациями, а атрибуты классов(например) вписаны явным образом(не через отношения, а прямо в тело класса).
опять же вопрос об уровне где и как использовать ассоциации и тем более агрегации.
Понимаете явное указание атрибута типа объект среди атрибутов другого класса по сути есть уже указание на решение, но задача аналитика не указать конкретное решение по реализации, а сказать что нужно реализовать. Ведь Вы не будете спорить, что ассоциацию можно реализовать по-разному? В то время как явное указание атрибута жестко будет определять и способ реализации связи между двумя объектами - через ссылку, массив, коллекцию или создание отдельного класса. Т.е. если на модели Вы укажите просто ссылку на объект, как это принято в C++, а в реальности вам потребуется сделать нечто иное - не приведет ли это к логическому разрыву между реализацией и моделью - как впрочем часто и бывает?



***Множественная классификация и множественное наследование в реальном мире встречается довольно часто, другое дело, что современный ООЯ просто не позволяет просто воспользоваться этим.***
ну не очень то и часто множественная классификация(выражающаяся в множественом наследовании) встречаются в этом мире.
и она сводима к однократному наследованию. это можно показать, соббсно.
действительно. если вы решили что ваш класс должен находиться в двух классификациях сразу, то чтобы разделить "сцепившиеся классификации" вам можно просто расщепить класс на два - один для одной классификации, и другой - для другой. вообще сцепившиеся классификации говорят скорее о том, что классификация проведена неверно. с точки зрения математики классификация есть разбиение общего множества обьектов(ну или понятий) на непересекающиеся домены, поддомены и так далее до конечных подмножеств. непересекающихся даже в пределах одного разбиения-данной классификации. и вдруг получется, что другое разбиение(классификация) дает некий домен, что вы считаете эквивалентным домену из совершенно другого разбиения!!! йерунда получается. :)

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

***Т.е. Вы считаете ассоциации - простой аналитической дурью?***
это было слишком сильное утверждение с моей стороны. имелось ввиду что в области разработки софта увлечение стрелками сильно перегружает диаграмму, что резко снижает ее читабельность.

***А что вы понимаете здесь под "розой"***
Rational Rose.

***Т.е. единственная причина использовать автогенерацию - это лень?***
составлять диаграммы без генерации кода - пустая забава. она даже зря порой оплачивается. диаграммы классов, без генерации, и если этот код не проверен компилятором, может быть даже семантически неверной. например атрибут класса с неким типом, написанным явно, навроде
_my_attr: SomeClass внутри класса,
будет скорее всего проглочен системой, даже если SomeClass более нигде не описан. При генерации кода и его компиляции это будет обнаружено компилятором.
Итак диаграмма классов хороша для визуального анализа вашей системы, как набора классов, проведения этапа разбиения на модули, подсистемы, генерации кода, и генерации документации. с генерацией тестов никогда не работал, ничего сказать не могу.

***Трудно не согласиться, но не стоит ли все-таки различать аналитическую работу и собственно реализацию. Или Вы полагаете, что аналитика - суть пиар и ничего более?***
мощный вопрос. я лично со всем радикализмом считаю, что просто "аналитиков" в мире не бывает. аналитик обязательно должен знать предметную область, и особенности реализации. хотя бы неявно.
пример. я занимался разработкой компиляторов, например. вы например в этом не понимаете, но вы аналитик, и начинаете рисовать диаграммы работы компилятора. ну и что вы нарисуете? две три очевидных диаграммы, типа - подать файл на вход системы, если найдена ошибка, выдать сообщение куда-то с указанием типа ошибки и позиции в тексте. все. а это понятно и без диаграмм. и без аналитиков.
итак. если аналитик не понимает предметной области и особенностей реализации, он беспомощен.

***Может быть все дело в точке зрения? Что такое эти 500 классов - откуда они появились? Это классы предметной области? Или уже объекты программной реализации? Все ли 500 классов вам нужны для анализа одновременно?***
это классы - всего. разумеется они распадаются на подсистемы, часто различные приложения или службы, и так далее. но это система выполняющая некую общую задачу.
ну например представьте себе структуру типовой ос. и есть архитектор ос. задачи такого рода, разумеется, трудно решать только в виде текста на с++.

***Понимаете явное указание атрибута типа объект среди атрибутов другого класса по сути есть уже указание на решение, но задача аналитика не указать конкретное решение по реализации, а сказать что нужно реализовать. Ведь Вы не будете спорить, что ассоциацию можно реализовать по-разному? В то время как явное указание атрибута жестко будет определять и способ реализации связи между двумя объектами - через ссылку, массив, коллекцию или создание отдельного класса.***
если атрибут простого типа вроде
_is_correct:boolean
вы будете рисовать на квадратик класса boolean какую-то свободную от деталей реализации ассоциацию?
если вы архитектор верхнего уровня, не ваше дело рисовать атрибуты. вы должны рисовать методы. то есть составлять функциональные интерфейсы классов. а атрибуты всегда имеют прямое отношение к реализации. не хотите иметь отношения к реализации - рисуйте контракты - то есть функциональный набор.
рисуете атрибуты - думайте о реализации.
в случае если вы уверены, что у класса должен быть некий атрибут, что выразим как множество экземпляров неких других классов, типа ссылки на нечто во множественном числе...просто напишите
_name: PoolOfFoo. где PoolOfFoo - некий класс с собственной функциональностью(что вы должны тоже описать), и уже программер и пусть решает как этот Pool ему реализаовать.
Стрелка вообще ничего ему не скажет.
Ну генератор кода сделает из этой стрелки нечто вразумительное, по ему известным правилам. Но тогда это уже не выбор программиста, а выбор конфигурации паттернов генерации кода. Если вы их не знаете, не понимаете какой код они сгенерят,...то тут легко получить уязвимость с точки зрения адекватной реализации.

Хочу резюмировать. Диаграмма классов(и заложенные в ней возможности) адекватны именно реализационному этапу в разработке софта. Если вы собираетесь ее использовать только на этапе логического анализа верхнего уровня, и потом передать кодерам...то вы пропустили именно самый трудный и длительный этап - этап реализации, с генерацией кода. кодеры у вас окажутся в слишком свободной ситуации, и наверняка будут нести отсебятину, в результате которой система окажется незрелой во многих смыслах.
Если же вы дали систему классов сформулированную до конца, с требованием, что кодеры не имеют права менять состав классов без согласования с вами, и занесения это в диаграммы - то кодеры оказываются в жестких рамках и кстати, довольно часто это приветсвуют. поскольку им не нужно особо задумываться над тонкостями реализации. они просто наполняют тела методов нужным кодом. и если классы сформулированы верно, методы обычно довольно атомарны и не имеют сложной логики.
« Последнее редактирование: 02 Июня 2008, 01:24:44 от alys »



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



500 "голых" классов без разделения на уровни/пакеты -- скорее всего признак плохого дизйна. Даже если ваша модель реализации столь сложна -- то нужно позаботиться об инкапсуляции логики в некие контейнеры (модули, пакеты и т.п.), и активно выставлять "наружу" интерфейсы.
Говоря о "большом софте" и в частности ОС -- там тоже действуют простые способы борьбы со сложностью и следовательно энтропией -- а именно декомпозиция. Часть функциональности ОС реализована утилитами, функциональность которых ограничена.
"Politics is the art of looking for trouble, finding it, misdiagnosing it, and then misapplying the wrong remedies" (c)
Мой блог
http://www.yurybuluy.blogspot.com/



***500 "голых" классов без разделения на уровни/пакеты -- скорее всего признак плохого дизйна.***
я лично, ни в своей, ни в мировой практике, не встречал 500 "голых" классов в одном файле(видимо это вы хотите сказать)? :)
хотелось бы видеть ненормального способного на этот титанический труд.
труд воистину титанический поскольку только компиляция такого пакета будет составлять неприемлемое время, а уж работа с ним в редакторе - чистое самоубийство.
с чего вы взяли, что такие люди есть, и один из них - перед вами?



ос претендующая на современность имеет архитектуру сходную с микроядерной, и с динамической загрузкой модулей ос. от есть конфигурируется при запуске, и не требует априори значительных аппаратных ресурсов. она также имеет механизмы самоверификации, защиты от сбоев, и предоставляет задачам изолированные среды для выполнения. и это только базовая функциональность.
разумеется в одном файле написать такое - это подвиг
реальная архитектура - модульная и многослойная. с четким контролем и видимости обьектов и проникновения хода исполнения из слоя в слой.
« Последнее редактирование: 03 Июня 2008, 13:32:44 от alys »



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

А как быть с ОС, претендующей на полезность? А с ОС, претендующей на коммерческий успех? ;)

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

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

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

Действительно, йерунда получается. А СУБД вы тоже до сих пор только иерархические используете? ;)
greesha.ru

Реальность - это убийство прекрасной теории бандой мерзких фактов. (Роберт Гласс)



***Но такие задачи я бы отнёс... как бы это поточнее выразиться... к периоду внтриутробного развития технологий создания ПО.***
вы похоже утверждаете, что системный анализ и задачи системного программирования несовместимы :) и понятие системы в них разныя?
тогда дайте понятие системы, в том и другом случае, и покажите разницу.

***А СУБД вы тоже до сих пор только иерархические используете?***
представление данных и логическая классификация понятий - вещи разные.
классический пример из ООП.
есть два класса - шар и цвет.
если вы считаете что класс - цветной шар есть просто наследник от классов шар и цвет, то это грубая ошибка.
почему?
потому что если это не ошибка, то экземпляр класса цветной шар должен  отвечать утвердительно на два вопроса
- является ли цветной шар шаром? да!
-является ли цветной шар цветом? ... как вы ответите?

более тонкий пример.
класс мужчина(классификация людей) и класс - армейский генерал(классификация военных званий).
так вот реальный генерал иван петрович вовсе не может быть преставителем некоего класса наследника от мужчины и генерала. потому что такой класс есть строго говоря по ооп - кентавр типа мужчино-генерал.
а правильно так, либо нужно наследовать от мужчины и иметь атрибут военное звание...либо от генерала и иметь атрибут - персона. в зависимости от предметной области.
« Последнее редактирование: 03 Июня 2008, 22:38:18 от alys »



Alys, нажимаем на кнопочку ЦИТИРОВАТЬ, в результате в форме быстрого ответа появлется цитата. Править и что-то делать не удобно?
Согласен, хотя несложно переключиться на латиницу и написать для первой цитаты [/quotе]
а все последующие [quotе] [/quotе]

Но можно поступить проще. (Копируем текст ссылки, следует отметить что в эту форму бстрого ответа можно включить цитирование разных писем - просто нажимая кнопку ЦИТИРОВАТЬ)
Выделяем текст в форме быстрого ответа - копировать, нажать кнопку Ответ и вставить в окно редактор - уже проще и интереснее.

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



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




 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19