Uno de los beneficios de las clases de dominios enriquecidos es que puede llamar a su comportamiento (métodos) cada vez que tenga la referencia al objeto en cualquier capa. Además, tiende a escribir métodos pequeños y distribuidos que colaboran juntos. En las clases de dominio anémicas, tiende a escribir métodos de procedimiento gruesos (en la capa de servicio) que generalmente son impulsados por casos de uso. Por lo general, son menos fáciles de mantener en comparación con las clases de dominio enriquecidas.
Un ejemplo de clases de dominio con comportamientos:
class Order {
String number
List<OrderItem> items
ItemList bonus
Delivery delivery
void addItem(Item item) { // add bonus if necessary }
ItemList needToDeliver() { // items + bonus }
void deliver() {
delivery = new Delivery()
delivery.items = needToDeliver()
}
}
El método needToDeliver()
devolverá la lista de artículos que deben entregarse, incluida la bonificación. Se puede llamar dentro de la clase, desde otra clase relacionada o desde otra capa. Por ejemplo, si pasa Order
a ver, puede usar needToDeliver()
de seleccionado Order
para mostrar la lista de elementos que debe confirmar el usuario antes de hacer clic en el botón Guardar para conservar el archivo Order
.
Responder a un comentario
Así es como uso la clase de dominio del controlador:
def save = {
Order order = new Order()
order.addItem(new Item())
order.addItem(new Item())
repository.create(order)
}
La creación de Order
y LineItem
es en una sola transacción. Si uno de los LineItem
no se puede crear, no Order
se creará.
Tiendo a tener métodos que representan una sola transacción, como:
def deliver = {
Order order = repository.findOrderByNumber('ORDER-1')
order.deliver()
// save order if necessary
}
Todo deliver()
lo que esté dentro se ejecutará como una sola transacción. Si necesito ejecutar muchos métodos no relacionados en una sola transacción, crearía una clase de servicio.
Para evitar la excepción de carga diferida, utilizo el gráfico de entidad con nombre JPA 2.1. Por ejemplo, en el controlador para la pantalla de entrega, puedo crear un método para cargar delivery
atributos e ignorarlos bonus
, como repository.findOrderByNumberFetchDelivery()
. En la pantalla de bonificación, llamo a otro método que carga el bonus
atributo e ignora delivery
, como repository.findOrderByNumberFetchBonus()
. Esto requiere disciplina ya que todavía no puedo llamar deliver()
dentro de la pantalla de bonificación.