Коллеги, такой вопрос:
Имеется некая библиотека — часть некоторого проекта. Она работает. Имеется ее представление в Розе. Правда, это представление неполно т.к. оно было получено непосредственно из исходников и несколько облагорожено.
Собственно, вопрос: можно ли по этому представлению достаточно надежно оценить качество библиотеки с точки зрения легкости поддержки и расширения?
Здравствуйте, BB, Вы писали:
BB>Коллеги, такой вопрос: BB>Имеется некая библиотека — часть некоторого проекта. Она работает. Имеется ее представление в Розе. Правда, это представление неполно т.к. оно было получено непосредственно из исходников и несколько облагорожено. BB>Собственно, вопрос: можно ли по этому представлению достаточно надежно оценить качество библиотеки с точки зрения легкости поддержки и расширения?
ИМХО, можно, но в общем случае — поверхностно.
Структура классов: глубины иерархий классов, количество и характер связей классов, количество и характер "деревьев" классов.
Например, "зарезервированные" направления наиболее лёгкого расширения нешаблонной библиотеки будут видны характерными "ёлочками" классов.
Сложность классов: количество методов, количество полей (открытых/закрытых), количество конструкторов.
Много открытых полей — не есть очень хорошо. Большие классы — где-то больше 20 методов — тоже не рулез.
Насчёт надёжности такой оценки — в зависимости от того, насколько надёжно роза схватила исходный код, а то она может глюкодромить на шаблонах и как именно "облагорожен" результат импорта. Хорошо бы для начала разнести классы по модулям и логическим группам.
Но вообще, это зависит от того, какая библиотека и для чего предназначена. Например, динамические преобразования типов аргументов методов могут несколько смазать первоначальное представление.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Насчёт надёжности такой оценки — в зависимости от того, насколько надёжно роза схватила исходный код, а то она может глюкодромить на шаблонах и как именно "облагорожен" результат импорта. Хорошо бы для начала разнести классы по модулям и логическим группам.
ГВ>Но вообще, это зависит от того, какая библиотека и для чего предназначена. Например, динамические преобразования типов аргументов методов могут несколько смазать первоначальное представление.
На самом деле я, наверное, напустил тумана.
Эта библиотека достаточно проста, чтобы качество импорта не вызывало сомнений.
Более общий вопрос: что представляет трудности при расширении/поддержке? Есть ли какие-нибудь типовые проблемы, которые можно было бы обнаружить не проводя детального анализа? Может быть, какая-нибудь спецефичная форма иерархии наследования, ассоциаций и т.д (кольцо, елка, пентограмма )?
Здравствуйте, BB, Вы писали:
BB>На самом деле я, наверное, напустил тумана. BB>Эта библиотека достаточно проста, чтобы качество импорта не вызывало сомнений. BB>Более общий вопрос: что представляет трудности при расширении/поддержке?
Конфликт между желаемым и предусмотренным способом расширения. Тут надо отталкиваться от желаемого направления развития и структуры библиотеки.
BB>Есть ли какие-нибудь типовые проблемы, которые можно было бы обнаружить не проводя детального анализа? Может быть, какая-нибудь спецефичная форма иерархии наследования, ассоциаций и т.д (кольцо, елка, пентограмма )?
Вообще-то, знаешь, структура хорошей объектной библиотеки просто красиво выглядит. ИМХО, такая оценка должна быть не самым последним критерием для того, кто собирается эту библиотеку модифицировать.
Если смотреть по диаграмме классов, то стоит обратить внимание на:
Ромбовидное невиртуальное наследование;
Открытые поля класов (трудно проконтролировать способы изменения состояния объекта);
Очень большие объекты all-in-one (скорее всего их стоило бы разбить на несколько более мелких);
Иерархии с глубиной наследования где-то больше 3-5 уровней;
Отсутствие private/protected-секций (говорит о том, что классы, скорее всего небрежно проектировали);
Отсутствие const-методов (относительно ненадёжный критерий, конечно, но я бы "напрягся");
Обилие методов типа get_Value/set_Value;
И ещё стоит "окинуть взглядом" исходные коды методов, потенциальные проблемы могут быть спрятаны там:
Динамическое приведение типов сверху-вниз по иерархии наследования или просто обилие rtti;
Злоупотребление void*;
Очень большие методы (увидишь — поймёшь);
Ещё я посоветовал бы тебе поискать в инете материалы по ключевым словам "Object-oriented metrics".
Ну вот так или примерно так.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
[]
ГВ>Вообще-то, знаешь, структура хорошей объектной библиотеки просто красиво выглядит. ИМХО, такая оценка должна быть не самым последним критерием для того, кто собирается эту библиотеку модифицировать.
Все зависит от вкусов. Хотя они редко плохими у опытных архитекторов бывают.
ГВ>Если смотреть по диаграмме классов, то стоит обратить внимание на:
ГВ>
ГВ> Ромбовидное невиртуальное наследование;
Это как?
ГВ> Открытые поля класов (трудно проконтролировать способы изменения состояния объекта); ГВ> Очень большие объекты all-in-one (скорее всего их стоило бы разбить на несколько более мелких);
С большим интерфейсом имеется в виду, надеюсь.
ГВ> Иерархии с глубиной наследования где-то больше 3-5 уровней;
Не согласен. Глубина должна быть такой, какой должна быть. Хотя, конечно, больше пяти уровней — это только в дотнете или дельфах бывает.
ГВ> Отсутствие private/protected-секций (говорит о том, что классы, скорее всего небрежно проектировали); ГВ> Отсутствие const-методов (относительно ненадёжный критерий, конечно, но я бы "напрягся");
А вот в дотнете их вообще нет.
ГВ> Обилие методов типа get_Value/set_Value;
Не согласен. Я считаю, что свойства, в очень многих случаях они просто необходимы. ГВ>
ГВ>И ещё стоит "окинуть взглядом" исходные коды методов, потенциальные проблемы могут быть спрятаны там:
Другими словами: "Кроме этого, ознакомтесь с исходным кодом библиотеки." А что если она занимает 5 метров?
Рекомендации ниже относятся, скорее к рефакторингу, чем к проектированию.
ГВ>
ГВ> Динамическое приведение типов сверху-вниз по иерархии наследования или просто обилие rtti;
Зачем динамически сверху вниз приводить?
ГВ> Злоупотребление void*;
Это только для С++ справедливо. И вообще, другие языки значительно меньше провоцируют разработчика к подобным ошибкам.
ГВ> Очень большие методы (увидишь — поймёшь);
Есть такое, однако это уже чистейшей воды рефакторинг.
ГВ>
ГВ>Ещё я посоветовал бы тебе поискать в инете материалы по ключевым словам "Object-oriented metrics".
class B : public A {};
class C : public A {};
class D : public B, public C {};
ГВ>> Очень большие объекты all-in-one (скорее всего их стоило бы разбить на несколько более мелких); AS>С большим интерфейсом имеется в виду, надеюсь.
Угу, именно с ним.
ГВ>> Иерархии с глубиной наследования где-то больше 3-5 уровней; AS>Не согласен. Глубина должна быть такой, какой должна быть. Хотя, конечно, больше пяти уровней — это только в дотнете или дельфах бывает.
Так сложнее разобраться в том, что на самом деле может делать тот или иной класс.
ГВ>> Отсутствие const-методов (относительно ненадёжный критерий, конечно, но я бы "напрягся"); AS>А вот в дотнете их вообще нет.
Бяда
ГВ>> Обилие методов типа get_Value/set_Value; AS>Не согласен. Я считаю, что свойства, в очень многих случаях они просто необходимы.
Я имел ввиду не свойства, а примитивные аксессоры. Они порождают те же проблемы, что и открытые поля классов.
AS>Рекомендации ниже относятся, скорее к рефакторингу, чем к проектированию.
Ну, вопрос же в том и состоял — расширять и сопровождать.
ГВ>>
ГВ>> Динамическое приведение типов сверху-вниз по иерархии наследования или просто обилие rtti; AS>Зачем динамически сверху вниз приводить?
Ты у меня спрашиваешь? Не знаю. Наверное затем, что приводить снизу вверх не нужно, это компиляторы делают.
ГВ>> Злоупотребление void*; AS>Это только для С++ справедливо. И вообще, другие языки значительно меньше провоцируют разработчика к подобным ошибкам.
Или — злоупотребление object.
ГВ>>Ещё я посоветовал бы тебе поискать в инете материалы по ключевым словам "Object-oriented metrics". AS>Или refactoring.
И это — тоже полезно.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
ГВ>class B : public A {};
ГВ>class C : public A {};
ГВ>class D : public B, public C {};
ГВ>
Это концептуально оно ромбовидное, а так будет дерево.
хъ
ГВ>Так сложнее разобраться в том, что на самом деле может делать тот или иной класс.
Это определяется его интерфейсом, а не положением в иерархии.
хъ
AS>>Зачем динамически сверху вниз приводить?
ГВ>Ты у меня спрашиваешь? Не знаю. Наверное затем, что приводить снизу вверх не нужно, это компиляторы делают.
Не, ну почему все путают downcast и upcast? Я уже задолбался! Базовые классы, как правило, располагаються вверху.
хъ
ГВ>Или — злоупотребление object.
Это не злоупотребление. Узаконенная лажа перестает быть лажой.
Есть еще для дотнета, но для С++ я не видел. Видимо никому не нужно и слишком сложно.
Re[6]: UML и оценка качества...
От:
Аноним
Дата:
14.07.03 08:31
Оценка:
Здравствуйте, BB, Вы писали:
BB>Здравствуйте, Alexey Shirshov, Вы писали:
AS>>Или refactoring.
BB>А есть ли тулз для рефакторинга/c++ ? BB>Я нашел только для Java и Smalltalk и еще чего-то, не помню..., но не для c++
Есть Rational C++ Analyzer. Точно входит с состав RationalRose EE. Можешь скачать evaluation с www.rational.com
Здравствуйте, Alexey Shirshov, Вы писали:
AS>>>Зачем динамически сверху вниз приводить? ГВ>>Ты у меня спрашиваешь? Не знаю. Наверное затем, что приводить снизу вверх не нужно, это компиляторы делают. AS>Не, ну почему все путают downcast и upcast? Я уже задолбался! Базовые классы, как правило, располагаються вверху.
Угу, "сверху вниз" = "от базового к производному".
ГВ>>Или — злоупотребление object. AS>Это не злоупотребление. Узаконенная лажа перестает быть лажой.
Нет, её просто начинают считать не-лажой. На сложности анализа и прочая это никак не сказывается.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, BB, Вы писали:
BB>Собственно, вопрос: можно ли по этому представлению достаточно надежно оценить качество библиотеки с точки зрения легкости поддержки и расширения?
К сожалению, никакого волшебства в UML представлении нет. А в особенности в reverse engineered UML модели. Проблема в том, что из кода вытаскивается только статическая диаграмма классов. Информация о поведении системы (жизненном цикле объектов, потоках данных, возможных состояниях системы, типовых сценариях взаимодействия объектов) в ней не содержится. Так что первая проблема состоит в том, что этой информации часто просто _недостаточно_ чтобы понять как работает система. Хотя если вам все-таки это удалось, значит дизайн действительно скорее всего неплох (но это еще не значит, что библиотеку будет легко расширять в контексте _Ваших_ задач).
Также, по формальным признакам (степень "ромбовидности" иерархии наследования, процент "виртуальности" функций, и т. д.) _вообще_говоря_ нельзя выдать заключение о легкости поддержки продукта в будущем и качестве дизайна, а то было-бы все слишком просто: сокращаем глубину наследования, запрещаем множественное наследование, и, — вуаля! — получаем замечательную библиотеку! К сожалению, придется думать или полагаться на экспертные заключения. Наличие reverse engineered диаграммы классов чуть упрощает дело (не придется строить ее руками), хотя на больших и сложных системах автоматически построенные диаграммы совершенно бесполезны — на них слишком много ненужных деталей.
Резюме и ответ на Ваш вопрос: Наличие reverse engineering UML модели _само_по_себе_ не помогает (но и не мешает) оценить качество дизайна. Но одного этого представления во многих случаях не достаточно, чтобы выдать интересуещее Вас заключение (придется работать с исходным кодом/читать документацию и думать).
Вообще, по UML-диаграмме (полагаю, речь идет о диаграмме классов) можно довольно много сказать о программном продукте (библиотека, программа, компонент, ...), — как о качестве дизайна в целом, так и о возможностях расширения / поддержки. В случае с реверс-инжиниирид моделью, — надо смотреть конкретно что за модель получилась. Конечно, качество такой модели хуже чем написанной человеком, поскольку человек акцентирует нужные моменты и опускает нестоящие внимания. Но для небольшой библиотеки вполне реально получить наглядные модели. Дайте взглянуть на Вашу модель опытному программисту-дизайнеру, и он Вам ответит на Ваш вопрос.
PS О простоте поддержки говорит не только сама модель (т.е. дизайн), но и исходный код. Насколько хорошо написан. Во-вторых, проще ответить на вопрос о простоте внесения конкретных изменений, чем на вопрос о "простоте поддержки вообще".
В целом согласен. Только забыл упомянуть что это только для C++. И еще, наличие открытых ацессоров зависит от использования данного объекта. Если он выступает в роли контекста, то он по определению является набором полей с низким количеством функциональности.
А вообще, я бы дополнил.
1. Нужно оценить можно ли по именам узнать функциональность и назначение объекта.
2. В классе не должно быть больше 1-2 функиональности.
Конечно информация о связях дает значительно больше, более полезной, информации о качестве.
Здравствуйте, t.w., Вы писали:
BB>>Заранее спасибо.
TW>Вообще, по UML-диаграмме (полагаю, речь идет о диаграмме классов) можно довольно много сказать о программном продукте
sure.
Особенно если комментарии присутствуют,
и из них понятно зачем нужна та или иная совокупность классов.
А метрика -это отдельная вещь — как стиль, не всегда язык выражения идей определяет смысл идей.
Пример:
Вот смотришь на структуру MFC — и его из нее видно ?
Несколько отнаследованных линеек, и что?
(библиотека, программа, компонент, ...), — как о качестве дизайна в целом, так и о возможностях расширения / поддержки. В случае с реверс-инжиниирид моделью, — надо смотреть конкретно что за модель получилась. Конечно, качество такой модели хуже чем написанной человеком, поскольку человек акцентирует нужные моменты и опускает нестоящие внимания. Но для небольшой библиотеки вполне реально получить наглядные модели. Дайте взглянуть на Вашу модель опытному программисту-дизайнеру, и он Вам ответит на Ваш вопрос.
Без поведения, которое не задается в генерируемом UML, и не понимается в диаграммах взаимодействия даже рисованных вручную-
понять несколько сложно,
а вот по тектсу программы — очень даже можно.
Еще критерий — понятность названий,
следование стандартам обознаений.
Я не помню, есть ли такая возможность у Розы, но в Тугезере я бы запустил набор метрик и аудитов — получается на выходе достаточно много (а может — и слишком) информации, на основании которой можно сделать выводы как по структуре в целом, так и по отдельным классам.
Здравствуйте, BB, Вы писали:
BB>Коллеги, такой вопрос: BB>Имеется некая библиотека — часть некоторого проекта. Она работает. Имеется ее представление в Розе. Правда, это представление неполно т.к. оно было получено непосредственно из исходников и несколько облагорожено. BB>Собственно, вопрос: можно ли по этому представлению достаточно надежно оценить качество библиотеки с точки зрения легкости поддержки и расширения?
BB>Заранее спасибо.
Посмотри вообще архитектура понятна или нет. После часа исследования вообще понятно какие основные (3-5 штук) подсистемы? Как они взаимодействуют? Можно сказать про подсистемы/классы кто за что отвечает? Или нет?
Потом посмотри на концептуальную целостность. С этим посложнее, но можно постараться оценить.
Я бы это постарался оценить в первую очередь. Метрики тут не помогут, а без этого сложно будет с проектом работать.
Здравствуйте, BB, Вы писали:
BB>Здравствуйте, Alexey Shirshov, Вы писали:
AS>>Или refactoring.
BB>А есть ли тулз для рефакторинга/c++ ? BB>Я нашел только для Java и Smalltalk и еще чего-то, не помню..., но не для c++