Эта статья пытается продемонстрировать, что Java может быть более продуктивной, чем Ruby. Мы собираемся разработать то же приложение из статьи Rolling with Ruby on Rails Revisited ( часть 1 и часть 2 ), но с использованием POJO, аннотированных JPA и Model Driven Framework, в данном случае OpenXava . В результате с меньшим количеством кода и меньшим временем вы получаете более мощное приложение.
Рубин и рельсы: регрессивный каркас
Рубин на рельсах такой элегантный, такой легкий, такой продуктивный. Я не могу не читать и постоянно слышать эти комментарии. Например, статья Билла Уолтона «Возвращение к Ruby on Rails» говорит:
« Что бы вы подумали, если бы я сказал вам, что вы можете разрабатывать веб-приложения по крайней мере в десять раз быстрее с Rails, чем с типичной средой Java?»
К сожалению! В десять раз быстрее!
Что ж, после этих комментариев я решил изучить Ruby on Rails. Мне нужно знать истинный ключ производительности и счастья программиста.
После того, как я попробовал RnR, я обнаружил, что это очень классический фреймворк со старыми техниками:
-
Ruby — это динамически типизированный язык, такой как Smalltalk . Я предпочитаю статически типизированные языки.
-
Scaffolding — это пассивная генерация кода, как мастера IDE или AppFuse . Я предпочитаю активную генерацию кода или, что еще лучше, генерацию кода вообще нет.
-
Ориентированность на реляционную базу данных: генераторы кода и ActiveRecord продвигают концепцию сначала в таблицах, а затем в классах. Я предпочитаю более чистый OO, как Hibernate , JPA или даже ODBMS .
-
MVC : я ищу что-то более новое и лучшее, чем старая платформа MVC.
Проблема Java: разработчики Java
Производительность в мире Java — это культурная, а не техническая проблема. То есть это не ошибка Java, это наша ошибка, нам, разработчикам Java, необходимо спроектировать очень красивые архитектуры, применять везде шаблоны GoF , делать все повторно используемое, размещать 3 уровня во всех наших системах и использовать веб. услуги для всех. Мы не ищем простоты, поэтому не нашли ее. Но Java — это очень элегантный язык, который позволяет упростить подход к разработке программного обеспечения.
Производительность Java: другой путь
Способ повышения производительности — использование подхода, управляемого моделями. То есть разработать часть модели и только часть модели нашего приложения и использовать инфраструктуру для создания из нее всего приложения. MDA , OpenXava , Trails , NakedObjects , RomaFramework и JMatter являются примерами этого подхода.
Цель
Это основной экран нужного приложения:
По сути, приложение должно делать три вещи:
-
Показать список всех рецептов.
-
Создание новых рецептов и редактирование существующих рецептов.
-
Присвойте рецепт категории (например, «десерт» или «суп»).
Ruby on Rails первый спринт
Первый шаг с использованием RnR — это создание нового проекта, из командной строки вы должны написать:
$ rails cookbook2
Теперь вы должны создать и настроить базу данных.
Затем пришло время написать ваш первый код, в данном случае код SQL:
drop table if exists recipes;
drop table if exists categories;
create table categories (
id int not null auto_increment,
name varchar(100) not null default '',
primary key(id)
) engine=InnoDB;
create table recipes (
id int not null auto_increment,
category_id int not null,
title varchar(100) not null default '',
description varchar(255) null,
date date null,
instructions text null,
constraint fk_recipes_categories foreign key (category_id) references categories(id),
primary key(id)
) engine=InnoDB;
Очевидно, вы должны выполнить эти предложения в вашей базе данных.
И последний шаг — генерация кода Ruby, вам нужно всего лишь выполнить следующую команду в оболочке вашей ОС:
$ ruby script\generate scaffold recipe recipe
$ ruby script\generate scaffold category category
Да. У вас есть самая первая версия вашего RnR-приложения, готовая к запуску.
Да, очень мало работы, простая «создание таблицы» и выполнение мастера. Посмотрим результат.
Результат Rails
Это результирующее приложение:
Маленькая работа. Маленький результат
JPA на OX первый спринт
Продолжайте использовать OpenXava . Первый шаг с использованием OpenXava — создание нового проекта:
$ ant CreateNewProject.xml -Dproject=CookBook
Теперь вы должны создать и настроить базу данных.
Затем пришло время написать ваш первый код, в данном случае код Java:
Recipe.java:
package org.openxava.cookbook.model;
import java.util.*;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
@View(members="title; description; date; instructions")
public class Recipe {
@Id @GeneratedValue @Hidden
private Integer id;
@Required @Column(length=100)
private String title;
@Column(length=255)
private String description;
private Date date;
@Stereotype("HTML_TEXT")
private String instructions;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getInstructions() {
return instructions;
}
public void setInstructions(String instructions) {
this.instructions = instructions;
}
}
Category.java:
package org.openxava.cookbook.model;
import java.util.*;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
public class Category {
@Id @GeneratedValue @Hidden
private Integer id;
@Required @Column(length=100)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
И последний шаг — создание схемы dababase, вам нужно только выполнить следующую цель ant из вашего проекта:
$ ant updateSchema
Да. У вас есть самая первая версия приложения OpenXava, готовая к запуску.
Да, очень мало работы, простые POJO и выполнение updateSchema. Посмотрим результат.
Результат OpenXava
Это результирующее приложение:
Обратите внимание, что пользователь может создавать, обновлять, удалять, генерировать PDF из списка, экспортировать список в Excel, упорядочивать по каждому столбцу, разбивать на страницы с поддержкой больших наборов результатов и фильтровать данные. Более того, вы можете развертывать напрямую, без кода, только выполняя цель ant, ваше приложение на портале JSR-168 , а внешний вид портлета OpenXava адаптируется к внешнему виду портала.
Это первое приложение, готовое к производству.
Маленькая работа, отточенный результат.
С философской точки зрения разница между RnR и OX заключается в том, что в RnR вы сначала пишете таблицы, а в OpenXava — сначала классы.
Контроллеры
Rails сгенерировал для вас логику контроллера для базового CRUD, вы можете увидеть его здесь:
С другой стороны, OX не генерировал никакого кода для CRUD, OpenXava просто имеет общий код для выполнения CRUD и печати, и он присваивается автоматически всем сущностям. Вы можете написать свою собственную общую логику CRUD или написать конкретную логику для конкретной сущности, но у вас нет кода контроллера для каждой сущности. Таким образом, у вас будет меньше кода для обслуживания, и вы сможете изменить логику всех модулей CRUD, соприкасающихся в одном месте.
То есть для контроллеров Rails использует сгенерированный код, в то время как OX использует общий код.
Вы можете узнать больше о контроллерах OX в вики OpenXava .
Добавление отношений
Для добавления отношения из категории в рецепт в Ruby вы должны написать следующий код в category.rb :
и этот в recipe.rb :
Да, довольно просто. Но у вас есть больше работы. Вы должны отредактировать cookbook2 \ app \ views \ recipe \ _form.rhtml и добавить следующий код:
<p><label
for="recipe_category_id">Category</label><br/>
<%= select("recipe", "category_id", Category.find(:all).collect
{|c| [c.name, c.id] }) %></p>
Результат:
Со своей стороны, в OpenXava вы должны определить отношения, используя JPA в Category.java :
@ManyToOne(optional=false) @DescriptionsList
private Category category;
и в Recipe.java :
@OneToMany(mappedBy="category")
private Collection<Recipe> recipes;
И вам не нужно трогать любой HTML-подобный код. Ваше приложение покажет только это:
У вас есть ссылка для изменения или создания новых категорий отсюда.
Без добавления какого-либо дополнительного кода, если пользователь перейдет в модуль «Категория», он получит набор рецептов в каждой категории, как показано ниже:
На данный момент RnR-приложение по-прежнему не имеет этих функций, вам нужно написать несколько Ruby и HTML в коде, чтобы получить тот же эффект.
Основное различие между RnR и OX здесь заключается в том, что в OX вы не пишете HTML-подобный код, в действительности вы вообще не пишете код пользовательского интерфейса.
Расчет начального значения
Следующим шагом в учебнике по Ruby on Rails является создание начального значения для свойства. В RnR вы должны отредактировать код контроллера, чтобы добиться этого. Давай увидим это:
Вы изменяете метод new и update, добавляя строку:
@recipe.date = Time.now
Эквивалентом в OX является добавление аннотации @DefaultValueCalculator в модель:
@DefaultValueCalculator(CurrentDateCalculator.class)
private Date date;
Вы получаете тот же эффект более декларативным способом.
Что, в то время как в RnR вы помещаете код на контроллер, в OX код для вычисления начальных значений, для валидаций и для бизнес-логики в целом находится на модели. OX способствует перемещению бизнес-логики от контроллера к модели.
Любопытно, что в статье RnR говорится: «Я изменил файлы модели, поэтому мне нужно перезапустить наш веб-сервер». При использовании Eclipse WTP мне нужно всего лишь нажать Ctrl-B и нажать кнопку обновления в моем браузере, чтобы увидеть изменение моей модели в моем приложении OpenXava.
Вывод
Основное различие между Ruby on Rails и OpenXava заключается в том, что RnR — это инфраструктура MVC, вам нужно написать модель, представление и контроллеры, а OX — это управляемая моделью среда, вам нужно только написать модель. Результат — меньше кода для лучшего приложения.
Другое большое отличие состоит в том, что RnR использует пассивную генерацию кода; то есть он генерирует код для вас, но после него, если вы хотите расширить или уточнить код, вы должны отредактировать сгенерированный код. OpenXava не использует генерацию кода, единственный код, который у вас есть, это код, который вы пишете.
Вы можете найти производительность во вселенной Java.
Рекомендации
- OpenXava сайт
- Повторное рассмотрение статьи с Ruby on Rails ( часть 1 и часть 2 )
- Другие модельно-ориентированные фреймворки: Trails , NakedObjects , RomaFramework и JMatter