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 Ordera ver, puede usar needToDeliver()de seleccionado Orderpara 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 Ordery LineItemes en una sola transacción. Si uno de los LineItemno se puede crear, no Orderse 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 deliveryatributos e ignorarlos bonus, como repository.findOrderByNumberFetchDelivery(). En la pantalla de bonificación, llamo a otro método que carga el bonusatributo e ignora delivery, como repository.findOrderByNumberFetchBonus(). Esto requiere disciplina ya que todavía no puedo llamar deliver()dentro de la pantalla de bonificación.