¿Qué tan aceptable es mantener la lógica de negocios fuera de las entidades (en clases de servicio separadas)?

7

Nos enseñaron que los objetos son cosas autocontenidas con datos y comportamiento y, por lo tanto, deben tener métodos que actúen sobre sus atributos. Pero hay varias situaciones en las que no se observa este acoplamiento entre entidades y su comportamiento:

  • Los marcos de entidades (como .NET con POCO y Enterprise Java con entidades POJO) estipulan que las operaciones de CRUD / persistencia / búsqueda deben ser realizadas por administradores de entidades externos (y repositorios) y no por las entidades mismas, es decir, tenemos el código entityManager.save(entity) y no entity.save() ;
  • Los motores de reglas de negocios son los ejemplos más visibles de separación de la lógica de negocios de las entidades: las reglas de negocios forman un código completamente diferente (incluso en diferentes idiomas) de las entidades. P.ej. JBoss Drools o IBM ILOG u otros motores de reglas. El paradigma de reglas de negocios se puede usar para la extrapolación de la programación de OO: en OO consideramos datos y métodos, pero en la web semántica podemos considerar ontologías y reglas lógicas / de negocios que actúan sobre ABox o TBox de ontologías, dos idiomas completamente diferentes. sistemas de razonamiento.
  • La computación distribuida estipula el uso de la serialización y la deserialización de objetos y la comunicación de esos objetos a través de la red: tenemos XML, formatos binarios nativos o JSON para esto. Por lo general, solo los datos se comunican a través de la red y la lógica comercial se mantiene en una capa y no hay tecnología para mover la lógica empresarial a través de la red y las plataformas, por ejemplo. no hay traducción automática y comunicación de la lógica de negocios cuando las entidades Java se traducen en objetos JSON y se exponen a través de la API REST a la interfaz Angular 2. La lógica de negocios generalmente se mantiene en un lado (por ejemplo, en Java).
  • Se dice que el modelo de dominio OO debe reflejar / modelar el mundo real. Y a veces los objetos del mundo real no tienen lógica empresarial dentro de ellos. P.ej. hay conceptos sobre las calculadoras, por ej. calculadoras de impuestos, calculadoras de salarios, etc. Por lo tanto, escribimos calculator.recalcTaxes(invoice) y no invoice.recalcTaxes . El enfoque anterior nos permite aplicar diferentes calculadoras en diferentes casos = por ejemplo, a través de las legislaciones. No estamos obligados a construir una jerarquía de herencia compleja, simplemente porque existen diferentes métodos de negocios, simplemente aplicamos diferentes servicios / calculadoras de negocios a los mismos datos.

Teniendo en cuenta esos argumentos pro que separan la lógica empresarial de los datos / entidades - ¿qué tan aceptable es hacer esta separación como la regla general de diseño para mi proyecto de software empresarial? ¿Cuáles son los argumentos en contra de separar la lógica empresarial? de los datos?

    
pregunta TomR 28.12.2016 - 21:29

3 respuestas

5

Creo que el problema al que se refiere está relacionado con las características de una sola clase y el nivel de descomposición de clase establecido para un problema considerado. Cada uno de sus ejemplos suena razonable teniendo en cuenta las características de la clase. Por otro lado, hay muchos escenarios en los que los datos están ligados a la lógica. En tal caso, se denomina comportamiento de clase más que lógica empresarial.

Cada uno de estos debe considerarse por separado teniendo en cuenta al menos lo siguiente:

  • ¿La lógica de negocios representa la lógica externa o el comportamiento interno de la clase?
  • ¿La clase representa el modelo?
  • ¿Qué es el nivel de complejidad lógica?
  • ¿cuál es la probabilidad de que la lógica de negocios cambie?
  • ¿cuál es la probabilidad de que se apliquen nuevas reglas de lógica de negocios al objeto?
  • ¿la clase está expuesta a un entorno externo?
  • ¿la lógica de clase está distribuida en niveles en el enfoque de n niveles?

El tío Bob introdujo algunos principios de diseño orientado a objetos llamados SOLID . Uno de los principios, Principio de Responsabilidad Única (SRP) describe exactamente a qué se refiere:

  

una clase debe tener una sola responsabilidad (es decir, solo un cambio potencial en la especificación del software debería poder afectar la especificación de la clase)

Esa es la regla general. Lo que es importante (también recomendado por Martin), el principio debe usarse solo en los escenarios en los que la clase se considera en la cadena de cambios / tiene una razón para cambiar . En otro caso, el uso del principio puede aumentar la complejidad del código ...

Ejemplo breve: usted crea (o utiliza) una clase llamada Lista que contiene el modelo (Elementos) y el comportamiento (Agregar, Editar, Eliminar) en lugar de dos clases (ListContainer y ListManager). Eso debido a la complejidad innecesaria introducida en el problema que es el comportamiento de clase "interno". Además, la forma en que la lista gestionará los objetos nunca cambiará.

    
respondido por el tom3k 28.12.2016 - 22:34
4

Si está hablando literalmente de lógica de negocios como en, es para una lógica de negocios y no de dominios en general, creo que la mayoría de las entidades tienen una lógica impuesta por influencers externos o por el contexto (le damos un descuento si. ..). Es por eso que la programación empresarial puede ser tan frustrante porque las cosas pueden parecer arbitrarias. Las entidades no siempre coinciden con el mundo real, pero el mundo como el negocio lo percibe en diferentes circunstancias. Solo hay un cliente llamado "Acme, Inc." pero tenemos que tener dos entradas porque nuestro sistema solo permite que se les asigne una persona de ventas, y necesitamos que tengan dos debido al primo de alguien de yadda-yadda-yadda. No se preocupe, no tiene que hacer esto todo el tiempo (como si eso importara), así que estoy seguro de que puede programar la computadora para hacer esta única excepción al calcular el total de sus compras.

En los EE. UU., si contrata a un contratista, debe darles un formulario de impuestos 1099 si le facturan más de $ 400. Esta regla no es parte del contratista o incluso de una factura en particular, sino una regla de impuestos del gobierno externo que analiza el agregado de facturas para un año fiscal determinado. Esta regla podría incluso fluctuar de un año a otro. Tratar con organizaciones sin fines de lucro puede presentar otra preocupación. Realmente necesitas algún tipo de calculadora de impuestos para esto.

Cuando no separa su lógica correctamente, los usuarios pueden comenzar a usar sus entidades de una manera que no había planeado, porque la lógica de negocios está muy vinculada a la entidad. La entrada de datos de la dirección del cliente debe ser muy sencilla, pero ¿alguna vez ha visto: AddressLine3="c / o John Smith" porque la aplicación no distingue entregas comerciales de residencias privadas? Como no tiene una lógica separada para imprimir etiquetas de correo, los usuarios hacen todo tipo de cosas para evitar la falta de información de direcciones separada de la lógica de impresión de direcciones.

Las reglas comerciales tienden a ser una combinación de factores y rara vez se cortan y se secan para una entidad determinada. Puede poner la lógica en una entidad comercial, pero creo que se encontrará refactorizando esto cuando todos finalmente identifiquen cómo se hacen o se harán las cosas realmente.

    
respondido por el JeffO 29.12.2016 - 00:24
1
  

qué tan aceptable es hacer esta separación como la regla general de   ¿Diseño para mi proyecto de software empresarial?

Depende del paradigma que quieras seguir. Básicamente, está describiendo la programación de procedimientos (un conjunto de instrucciones actúa sobre los datos) frente a la programación orientada a objetos (un objeto lleva a cabo una unidad de comportamiento mediante la solicitud de otros objetos y también unidades de comportamiento).

Como le gusta señalar a Alan Kay, casi no hay lenguajes / sistemas reales orientados a objetos reales. Por lo tanto, no es sorprendente que los paradigmas de programación de procedimientos se introduzcan en los idiomas "OO" como se indica. Sin embargo, no quiero decir que el paradigma procesal sea necesario, solo que a menudo el pensamiento procedimental (como lo llama Dave West) es más fácil cuando se escribe un código. Existe una gran cantidad de los llamados códigos "orientados a objetos" que, de hecho, no están orientados a objetos.

Personalmente, me suscribo a la idea de que si va a seguir un paradigma de procedimiento, debe utilizar un lenguaje de procedimiento (o las características de procedimiento de un idioma que admita tanto el procedimiento como la OO). Intentar convertir el código de procedimiento de la bocina en un código que también está intentando hacer lo más orientado a objetos posible, puede crear un poco de lío.

    
respondido por el Cormac Mulhall 29.12.2016 - 13:52