Общий раздел > ПО Аналитика

Сравнение CASE-средств для кодогенерации ( от eUML2 до Enterprise Architect)

(1/4) > >>

singleton:
...a помимо Enterprise Architect за борт были выкинуты:



* MagicDraw 14
* Visual Paradigm 6.1 Enterprise
* Rational RSD 7
* Borland Together
* Poseidon 6.0 и ArgoUML
* Netbeans UML Plugin
* Eclipse Omondo Plugin
* Fujaba
* MID Innovator 2007
Все это добро было протестировано в перспективе дизайнера (не путать с аналитиком) при подготовке модели к реализации на Java 6.0. Таким образом сформировались минимальные требования к UML инструментам, которые, будучи далеко не полными, позволили все-же отсеять почти всех кандидатов. Требования эти, в свете сказанного, были простые и понятные, :

1. Class Diagrams, UML2
2. Good Associations Support, 1:1 / 1:n / qualifiers
3. Contemporary code generator, type safe java 1.5 generics

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

 - - - to be continued - - -

 

singleton:
- - -
ПАРА СЛОВ В НАЧАЛЕ

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

Во-первых, захотелось обратить внимание комьюнити на беспрецедентный кризис в области средств поддержки uml моделирования. Заявления типа "Full UML 2.1 support",  "XMI 2.1 support" или "sophisticated round-trip engineering" это пустой звук, вранье, маркетинг - называйте как хотите. Поразительно, но программисты именитых фирм не в состоянии написать нормальные средства поддержки uml, которые будут делать то, что от них ожидается. Это при том, что потребители находятся  в том же домэйне, что и создатели: те же, по-сути, программисты.

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

 - - -
КАК ТЕСТИРОВАЛ:

Итак, сконцентрируемся на Диаграммах Классов, а точнее на ассоциативных связях. Собственно,  для простоты эксперимента только их и будем рассматривать. Выбрав таким образом  наше самое-самое-главное и фсе, с точки зрения дизайнера, можем смело привязывать к позорному столбу всех тех, кто даже к таким вещам отнесся не очень серьезно. Ведь без ассоциаций никуда!


Свойства ассоциаций (для удобства последующей оценки) я поделил на три функциональные группы


* Базовые свойства: => макс 3 пункта
 - navigable (bi, a-b, b-a),
 - multiplicity (1, 0..1, 1..*, *, итд)
 - special: aggregation, composition

* Последовательности, множества, мультимножества:  => макс. 2 пункта
 - {unique}
 - {ordered}
 - их комбинация

* Qualifiers (Qualified Associations): => макс. 3 пункта
 - 1:1, "хэш"
 - 1:n,  "мультихэш" и, как следствие, все те же опции мультимножеств
 - несколько квалификаторов к рамках одной ассоциативной связи


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


* код неверный семмантически, либо синаксически:
=> оценка функ. группы понижается вдвое
* код верный, но не отвечает стандартам "type safety", реализуемым с помощью <generics> c 2004 года:
=>оценка функ. группы остается неизменной (+0%)
* код верный и обеспечена "type safety", с помощью Java 1.5 <generics> :
=>оценка функ. группы удваивается

singleton:
- - - РЕЗУЛЬТАТЫ ТЕСТА - - -


Sparx Enterprise Architect 7.0 Score: 9.5 points from 16


* basic features: 3 points x 2 = 6

Пришлось немного покопаться, прежде чем удалось хитростью уговорить EA генерировать type safe код для множеств. В Options->Source Code Engineerig->Java следует прописать в строчке Default Collection Class вот это заклинание: "java.lang.Collection<#TYPE#>". К GUI претензий нет. 6 пунктов как с куста.



* (multi-)set options: 1 points x 2 = 2

EA умеет различать {ordered} множества. Как и в случае с базовами функциями, надо немного поколдовать и указать в опциях в качестве Collection Class for Ordered Multiplicity вот такую, например строчку  "java.lang.List<#TYPE#>" или "java.lang.LinkedHashSet<#TYPE#>".
В первом случае сгенерируются упорядоченные мультимножества (допускают дубликаты), во втором - упорядоченные множества. Одновременно создать в генерируемом коде обе эти разновидности не возможно. Для этого воспетому в рунете Архитектору элементарно не хватает поддержки {unique}.


* Qualified Associations: 3 points x 0.5 = 1.5 

Квалификаторы, поддерживаются! Но только на бумаге. Вернее в GUI. А вот с кодом возникли серьезнве проблемы. В частности код, сгенерированный по Qualified 1:1 Association ничем от обычной 1:1 Association не отличается. Если квалифиаторов несколько, это только усогубляет ситуацию... Итого один пункт с натяжкой.



Rational RSD 7. score 10 points from 16


* basic features: 3 points x 2 = 6
ibm-овский софт позволяет моделировать все базовые функции. Полученный в итоге код грамотно использует generic-шаблоны.


* (multi-)set options: 2 points x 2 = 4
Перед генерацией для всех видов (мульти-)множеств можно задать задать свои альтернативы java.util.Collection. Впрочем, заданные по умалчанию, чаще всего подойдут:

java.util.Collection;  // non-ordered, non-unique
java.util.List;            // {ordered}, non-unique
java.util.Set;          // non-ordered, {unique}
java.util.SortedSet;  // {ordered}, {unique}

Полученный в итоге код грамотно использует generic-шаблоны.


* Qualified Associations: 0 points
Перерыл все и... не нашел квалификаторов! Может я, конечно, не там искал, но больше получаса на поиски не было... 



Visual Paradigm 6.1 Enterprise score: 6 points from 16


* basic features: 3 points x 2 = 6

Парадигм подобно Rational RSD справляется с базовой задачей и генерирует безупречный код.


* (multi-)set options: 0 points x 0.5 = 0

Свойства  {ordered} и {unique} в парадигму Парадигмы как-то не вписались. И зря. 0 пунктов


* Qualified Associations: 0 points x 0.5 = 0 

Квалификаторов нет. На нет и суда нет. И пунктов тоже нет.



Borland Together 2006 R2 Score: 5.5 points from 16


* basic features: 3 points x 1 = 3

Борланд предлагает выбирать одну из 20 реализаций класса Collection каждый раз, когда надо создать новую 1:n связь. Хорошо это или плохо оценить не берусь. С одной стороны долго, с другой стороны больше свободы действий. Вручаем Борланду три пункта и фактор x1, т.к. код получается хоть и правильный, но актуальным его можно было назвать 4 года назад. До введения generics.


* (multi-)set options: 2 points x 0.5 = 1

Свойства {ordered} и {unique} отражены в GUI. Но на коде это никак не сказывается. Один пункт. В долг.


* Qualified Associations: 3 points x 0.5 = 1.5 

Квалификаторы тоже исключительно в GUI. Зато очень просто и удобно.



Poseidon 6.0 и ArgoUML Score: 4 points from 16


* basic features: 3 points x 1 = 3

ArgoUML и его коммерческий отпрыск Poseidon вот уже 3 года не в состоянии реализовать поддержку шаблонов. Форумные мольбы клиентов, заплативших за софт последние кровные, в последнее время просто игнорируются. В остальном же код получается корректный. С фактором х1 базовые функции приносят повелителю морей три очка.


* (multi-)set options: 1 points x 1 = 1

Хорошая новость: {ordered} констрэйн присутствует и даже более-менее грамотно переводится в java код (без generics). А плохая новость: {unique} нету. Совсем нету.


* Qualified Associations: 0 points x 0.5 = 0 

Квалификаторы не имеют место быть. А как громко была заявлена поддержка UML2...


MagicDraw 14. score: 4 points from 16


* basic features: 3 points x 0.5 = 1.5

волшебный художник позволяет моделировать все базовые ассоциативные функции. Но полученный в итоге код совершенно неверен. Элементарная "1:n" связь между Class1 и Class2 генерируется как
private Class2 m_class2;
т.е. кардинальность получается  "1:1"


* (multi-)set options: 2 points x 0.5 = 1

Свойства  {ordered} и {unique} есть. Но о генерации правильного кода говорить не приходится, по причине описанной выше.


* Qualified Associations: 3 points x 0.5 = 1.5 

Квалификаторы есть! Более того, их можно задать сколь угодно много для одной и той же ассоциации. Два пункта честно заработаны, но успех делим пополам, поскольку, опять же, код от MagicDraw  просто безобразие! (или, все же надо где-то что-то подкрутить?)







Fujaba 5.0.4 Score: 3 points from 16


* basic features: 3 points x 0.5 = 1.5

Для некоммерческого проекта весьма неплохо. GUI выглядит некузяво, но свое дело делает. А вот генерация кода, как и ожидалось, для продуктивных целей не подходит. Диагноз примерно как и в случае с MagicDraw: неважно какие нюансы вводились в модель ассоциации двух классов. На выходе всегда простейшая 1:1 кардинальность, типа

public class Class1 {
   private Class2 bbb;
}

Основное различие: 900$. Такова цена MagicDraw UML Professional Edition for Java


* (multi-)set options: 0 points x 0.5 = 0

{ordered} и {unique} fujaba профуябила.


* Qualified Associations: 3 points x 0.5 = 1.5 

Квалификаторы, к моему удивлению есть! Но кода для них опять нет.



Netbeans UML Plugin Score: 1.5 points from 16


* basic features: 3 points x 0.5 = 1.5

Очень и очень сырым оказался прилагаемый к Netbeans  UML Plugin. Если в modelling GUI базовыми функциями еще кое-как можно пользоваться, то получаемый код вообще не компилируется. Что-то они там намудрили, да так, что перлы типа Collection<void> не редкость. Ага, ушел итерировать пустоту...


* (multi-)set options: 0 points x 0.5 = 0

{ordered} и {unique} отсутствуют-с. Будем ждать и надеяться. А пока 0 пунктов.


* Qualified Associations: 0 points x 0.5 = 0 

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

 
 

Eclipse Omondo Plugin "EclipseUML" Score: not rated


* Коммерческий плагин для eclipse. Тестировать его не счел нужным, поскольку вот уже год как произошел раскол в стенах Omondo. R&D команда в полном составе весело позвякивая карабинами сбежала и организовала свою фирму: Soyatec. Там они по сей день совершенствуют новую версию своего продукта, переименованного из EclipseUML в eUML2. Но о нем отдельно и подробнее.
 


Soyatec eUML2 Score: 12 points from 16


* basic features: 3 points x 2 = 6

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


* (multi-)set options: 1 points x 2 = 2
 
{unique} отсутствуют, как и у многих других (интересно почему?) и это минус.
{ordered} множества поддерживаются, на выходе по-умолчанию Collection, либо List. Оба корректно параметризированы, разумеется.


* Qualified Associations: 2 points x 2 = 4 

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

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

модель:



результат (free edition):


--- Код: ---/**
 * @uml.property name="project"
 * @uml.associationEnd multiplicity="(0 -1)"
 *       inverse="person:model.Company"
 *       qualifier="key:java.lang.Object model.Project"
 */
private Map<Object, Collection<Project>> projectMap;

/**
 * Getter of the property <tt>project</tt>
 * @return Returns the project.
 * @uml.property name="project"
 */
public Map<Object, Collection<Project>> getProject()
{
return projectMap;
}

/**
 * Setter of the property <tt>project</tt>
 * @param company The project to set.
 * @uml.property name="project"
 */
public void setCompany(Map<Object, Collection<Project>> project) {
this.projectMap = project;
}

--- Конец кода ---

Результат возможный с помощью Velocity Templates (тока за дэнги)


--- Код: ---
/**
 * @uml.property name="project"
 * @uml.associationEnd multiplicity="(0 -1)"
 *      inverse="company:model.Project" qualifier="key:java.lang.Object model.Project"
 */
private Map<Object, Collection<Project>> projectMap;

/**
 * Getter of the property <tt>project</tt>
 * @return  Returns the projectMap.
 * @uml.property name="project"
 */
public Map<Object, Collection<Project>> getProject() {
return projectMap;
}

/**
 * Returns a set view of the keys contained in this map.
 * @return  a set view of the keys contained in this map.
 * @see java.util.Map#keySet()
 * @uml.property name="project"
 */
public Set<Object> projectKeySet() {
return projectMap.keySet();
}

/**
 * Returns a collection view of the values contained in this map.
 * @return  a collection view of the values contained in this map.
 * @see java.util.Map#values()
 * @uml.property name="project"
 */
public Collection<Collection<Project>> projectValues() {
return projectMap.values();
}

/**
 * Returns <tt>true</tt> if this map contains a mapping for the specified key.
 * @param key key whose presence in this map is to be tested.
 * @return  <tt>true</tt> if this map contains a mapping for the specified key.
 * @see java.util.Map#containsKey(Object)
 * @uml.property name="project"
 */
public boolean projectContainsKey(Object object) {
return projectMap.containsKey(object);
}

/**
 * Returns <tt>true</tt> if this map maps one or more keys to the specified value.
 * @param value  value whose presence in this map is to be tested.
 * @return  <tt>true</tt> if this map maps one or more keys to the specified value.
 * @see java.util.Map#containsValue(Object)
 * @uml.property name="project"
 */
public boolean projectContainsValue(Collection<Project> project) {
return projectMap.containsValue(project);
}

/**
 * Returns the value to which this map maps the specified key.
 * @param key key whose associated value is to be returned.
 * @return the value to which this map maps the specified key, or
 *      <tt>null</tt> if the map contains no mapping for this key.
 * @see java.util.Map#get(Object) 
 * @uml.property name="project"
 */
public Collection<Project> getProject(Object object) {
return (Collection<Project>) projectMap.get(object);
}

/**
 * Returns <tt>true</tt> if this map contains no key-value mappings.
 * @return <tt>true</tt> if this map contains no key-value mappings.
 * @see java.util.Map#isEmpty() 
 * @uml.property name="project"
 */
public boolean isProjectEmpty() {
return projectMap.isEmpty();
}

/**
 * Returns the number of key-value mappings in this map.
 * @return the number of key-value mappings in this map.
 * @see java.util.Map#size() 
 * @uml.property name="project"
 */
public int projectSize() {
return projectMap.size();
}

/**
 * Setter of the property <tt>project</tt>
 * @param value the projectMap to set.
 * @uml.property name="project"
 */
public void setProject(Map<Object, Collection<Project>> project) {
projectMap = project;
}

/**
 * Associates the specified value with the specified key in this map
 * (optional operation).
 * @param key key with which the specified value is to be associated.
 * @param value value to be associated with the specified key.
 * @return  previous value associated with specified key, or <tt>null</tt>
 * @see java.util.Map#put(Object,Object) 
 * @uml.property name="project"
 */
public Collection<Project> putProject(Object object, Collection<Project> project) {
return (Collection<Project>) projectMap.put(object, project);
}

/**
 * Removes the mapping for this key from this map if it is present
 * (optional operation).
 * @param key key whose mapping is to be removed from the map.
 * @return  previous value associated with specified key, or <tt>null</tt>
 *   if there was no mapping for key.
 * @see java.util.Map#remove(Object) 
 * @uml.property name="project"
 */
public Collection<Project> removeProject(Object object) {
return (Collection<Project>) projectMap.remove(object);
}

/**
 * Removes all mappings from this map (optional operation).
 * @see java.util.Map#clear() 
 * @uml.property name="project"
 */
public void clearProject() {
projectMap.clear();
}

 

--- Конец кода ---

до следующего раза. поправляйте и дополняйте :)

Ваш Dimitri Alexeev a.k.a. singleton

Galogen:

--- Цитата: singleton от 13 Сентября 2007, 05:20:55 ---до следующего раза. поправляйте и дополняйте :)
Ваш Dimitri Alexeev a.k.a. singleton

--- Конец цитаты ---
Дмитрий очень интересный и содержательный анализ.

Поскольку в дискуссиях форума частенько звучало негативное отношение к автогенерации кода. Мол зачем она нужна, она все равно кривая и косая. Теперь становится понятно, где и что кривое и косое.

Вопрос: А Вы в своей практике активно стараетесь использовать автогенерацию? Если да, то насколько это облегчает Вам жизнь? Насколько это вообще актуально?

singleton:

--- Цитата: Galogen от 13 Сентября 2007, 08:57:02 ---Вопрос: А Вы в своей практике активно стараетесь использовать автогенерацию? Если да, то насколько это облегчает Вам жизнь? Насколько это вообще актуально?

--- Конец цитаты ---

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

з.ы. Жаль что никто пока не поделился своим критическим мнением касательно справедивости результатов моего теста... Тот же MagicDraw, например, хоть и не в состоянии генерировать нормальный java-код (за что и получил только четверть пунктов), но ребята не поленились сделать экспорт в EMF2, а это открывает широкие возможности для внешних кодогенераторов на базе eclipse framework.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
Перейти к полной версии