2012-09-11 12 views
8

Disculpe cualquier desconocimiento aquí, soy bastante nuevo en DDD, así que sea amable.DDD en un sistema de reglas configurables

Estoy trabajando en un gran sistema de gestión de datos de configuración. El sistema se construye especificando fragmentos de configuración (como reglas comerciales, procesos y validaciones) en una sintaxis externa. Digamos que la sintaxis era un conglomerado de un DSL basado en Groovy y Drools.

Me gustan las ideas de simplicidad que ofrece DDD, específicamente separando las preocupaciones de infraestructura de los conceptos básicos del dominio.

Sin embargo, estoy luchando para aplicar algunos de los conceptos de DDD debido a la naturaleza configurable del sistema. Tanto el comportamiento (procesos), la validación y las reglas comerciales se definen de forma externa al sistema. Entonces las entidades en el dominio intrínsecamente no tienen comportamiento propio. Más bien son delicado para el asunto "Validador" o el "Motor de reglas" o el "Motor de flujo de trabajo".

Lo aclararé con un ejemplo. Digamos que mi sistema administra a los empleados de una empresa. Sin pensarlo demasiado, se imaginaría que tengo una Entidad de Empleado y una Entidad de Compañía en mi dominio.

Después de DDD, estoy tratando de modelar un escenario donde se promueve a un empleado. Es posible que vea un nuevo método en el empleado denominado promote (Employee.promote). Podríamos tener una regla de negocios que indique que un empleado no puede ser promovido dos veces en el mismo año (sí, todo está compuesto). Por lo tanto, podría tener algo como:

public void promote(EmployeeLevel newLevel) { 
    if (hasBeenPromotedThisYear(this) { 
    throw new InvalidPromotionException 

Pues bien, en la aplicación que estoy trabajando con esta regla de negocio se exterioriza a un motor de reglas. Después de DDD, podría hacer algo como:

if(promotionRules.isEligibleForPromotion(this) 

Para exteriorizar mis reglas. Sin embargo, el sistema es mucho más genérico que esto. La operación de "promoción" se define como un "Proceso" a través de una configuración externa. Entonces, en tiempo de compilación, ni siquiera sabría si tengo una operación de "promoción" disponible para este empleado. Así que mi objeto empleado se vuelve bastante simple desde la perspectiva del código, delegando toda la funcionalidad a la configuración. Podría ser algo como:

public class Employee { 
    public void execute(Process process) 

O, alternativamente

public class EmployeeProcess { 
    public void process(Employee employee) 

Mi pregunta es: ¿DDD siquiera tiene sentido en esta aplicación? ¿Debería simplemente modelar la colaboración de procesos, validaciones, reglas de negocio (motor de reglas) en un sentido no DDD?

Me gusta la arquitectura de cebolla, y puedo usar la interfaz de usuario -> Servicios de aplicaciones -> Núcleo -> Infraestructura para mantener una buena separación de preocupaciones. Pero el Núcleo podría ser los colaboradores mencionados anteriormente, a diferencia de los "conceptos de dominio" reales.

Parte de mí cree que, en este caso, los "conceptos de dominio" SON los validadores, procesadores, reglas de negocio porque constituyen el lenguaje omnipresente del que hablamos cuando hablamos de nuestro sistema. En este caso, tendría Entidades sin ningún comportamiento real (en su mayor parte), y conceptos de dominio en términos de Procesadores, Validadores, Motor de Reglas que realizan el comportamiento en el sistema.

Agregando un poco más de información. Dada mi pregunta anterior, estaba trabajando en una solución que se vería así:

org.example.aplicación

org.example.domain - Empleado - Compañía - EmployeeLevel

org.example.domain.shared - Proceso - BusinessRule - Validador

org.example.infrastructure

Afortunadamente, este pequeño fragmento agrega un poco de claridad.

Por lo tanto, los conceptos Process, BusinessRule y Validator se encontrarían dentro del dominio, pero apoyarían el modelo de dominio en términos de las cosas que hace el sistema.

Respuesta

2

De Wikipedia: diseño impulsado por el dominio

(DDD) es un enfoque para el desarrollo de software para necesidades complejas mediante la conexión profundamente la implementación de un modelo de evolución de los conceptos de negocio núcleo.

Creo que el validador, el proceso, la regla no son sus conceptos básicos de negocio. Esas son abstracciones de software bastante comunes.

No soy un gran admirador de DDD "por libro", pero para ser más "impulsado por el dominio" su DSL y sus reglas en realidad deberían construirse alrededor de los conceptos de su negocio para darle más sentido a eso .

Debajo del capó, todavía puede usar validadores, procesos, gerentes, ejecutores, etc., pero sus reglas/DSL serán más legibles si utiliza conceptos comerciales en ellas, en lugar de abstracciones de software.

ACTUALIZADO: Dado que está utilizando Groovy para definir su DSL, puede usar la función de resolución de nombres de métodos dinámicos de Groovy y la funcionalidad del generador para crear reglas y clases legibles. También puede aprovechar el principio de "convención sobre configuración" para enganchar algo de lógica. Por ejemplo, en Groovy se puede tratar de construir algo similar a:

if (employee is "promotable") { 
    start "promotion" for employee 
} 

is habrá un método en un objeto de dominio base que comprobar si hay existencia de digamos clase EmployeePromotableValidator, que por sí mismo también puede ser una maravillosa clase que aprovecha la expresividad de DSL de Groovy.

class EmployeePromotableValidator extends Validator<Employee> { 

    boolean validate(Employee employee) { 
    employee.age > 25 && employee.workingYears > 2 
    } 

} 

start habrá un método en su script regla de base que buscará EmployeePromotionProcess clase, que de nuevo puede ser una clase maravillosa.

patrón de especificación en este caso es muy simple, ya que básicamente se convierte en parte del lenguaje:

if (employee is "promotable" && 
    employee is "advanced" && 
    employee.salary < 10000) { 
    start("salary increase", "10%") for employee 
} 

En general, los DSL con la ayuda de (semi) los lenguajes funcionales como Groovy/Scala se pueden utilizar para ocultar abstracciones de software y hacer que su lógica de negocios sea más prominente en el código. Con Java simple terminarás con un montón de código de placa de caldera que eventualmente ocultará todas tus intenciones.

+0

Gracias por la respuesta. El modelo ciertamente tendrá conceptos comerciales en ellos (siguiendo el ejemplo, habría una entidad de Empleado y una entidad de Compañía con relaciones apropiadas). Es solo que esas entidades estarían desnudas en su mayor parte. Entonces, si lo estoy siguiendo bien, ¿los procesos, las reglas y los validadores se compartirán/cosas comunes en el dominio (siguiendo el patrón de especificación)? Este era el camino por el que bajaba. – noplay

+0

Ver la actualización de la respuesta –

+0

Gracias por la actualización. Estoy bastante seguro de que los conceptos de negocio serán centrales en el modelo de dominio. Se trabaja mucho en la configuración, pero hay muchos conceptos básicos de negocio que estarán activos en el doman. – noplay

1

Depende de qué es exactamente el dominio de su empresa.

Si está construyendo un gran crm extra configurable, algo que el constructor hace de todo, entonces su dominio comercial lo hace posible, por lo tanto, los nombres como Process, Executors, etc. son parte de su dominio.

Si está creando una aplicación que debe rastrear la información sobre los empleados y su capacidad de promoción, entonces su dominio comercial tiene que ver con los empleados, los cheques de pago y las mediciones de rendimiento. En este caso, trate Process, Executors y objetos similares como intrusos a su dominio.

En cierto modo, incluso el propio lenguaje de programación es una herramienta invasiva que difumina la solución del problema que está dibujando en su mente. Pero es necesario; de lo contrario, no podrías materializarlo.

+0

Gracias por la entrada. Normalmente, he visto caer el patrón de especificación en el dominio en un paquete/contexto compartido. No Procesar, Validadores, et. Alabama. entonces, ¿tiene sentido también caer en el dominio similar a lo que he visto con las Especificaciones? Creo que la implementación en esas interfaces/clases base cae en Infraestructura. – noplay