modelos gruesos vs. Lógica de negocios, ¿De dónde sacas la distinción?

15

Hoy entré en un acalorado debate con otro desarrollador de mi organización sobre dónde y cómo agregar métodos a las clases asignadas a la base de datos. Utilizamos sqlalchemy , y una parte importante de la base de código existente en nuestros modelos de base de datos es poco más que una bolsa de propiedades asignadas con un nombre de clase, una traducción casi mecánica de tablas de base de datos a objetos de python.

En el argumento, mi posición fue que el valor principal de usar un ORM era que puedes adjuntar comportamientos y algoritmos de bajo nivel a las clases asignadas. Los modelos son las clases primero y, en segundo lugar, persistentes (podrían ser persistentes al usar xml en un sistema de archivos, no es necesario que te importe). Su opinión era que cualquier comportamiento es "lógica de negocios", y que necesariamente pertenece a cualquier otro lugar que no sea el modelo persistente, que debe usarse solo para la persistencia de la base de datos.

Ciertamente, creo que hay una distinción entre lo que es la lógica de negocios , y debería separarse, ya que tiene cierto aislamiento del nivel inferior de cómo se implementa, y la lógica de dominio, que Creo que es la abstracción proporcionada por las clases modelo sobre las que se discutió en el párrafo anterior, pero me está costando saber qué es eso. Tengo una mejor idea de lo que podría ser la API (que, en nuestro caso, es HTTP "ReSTful"), ya que los usuarios invocan la API con lo que quieren hacer , distinto de lo que son permitido y cómo se hace.

tl; dr: ¿Qué tipo de cosas pueden o deberían ir en un método en una clase asignada cuando se usa un ORM, y qué se debe dejar afuera, para vivir en otra capa de abstracción?

    
pregunta SingleNegationElimination 29.03.2012 - 06:05
fuente

4 respuestas

10

Estoy mayormente contigo; su colega parece estar discutiendo por el modelo de dominio anémico o por duplicar el modelo en un "modelo de persistencia" sin beneficio obvio (estoy trabajando en un proyecto Java donde se hizo esto, y es un dolor de cabeza de mantenimiento masivo, ya que significa tres veces más trabajo cada vez que algo cambia en el modelo).

  

¿Qué tipo de cosas pueden o deben ir en un método en una clase asignada cuando se usa un ORM, y qué se debe omitir, para vivir en otra capa de abstracción?

Regla de oro: la clase debe contener lógica que describa hechos básicos sobre los datos que son verdaderos en todas las circunstancias. La lógica que es específica de un caso de uso debe estar en otro lugar. Un ejemplo es la validación, hay un interesante artículo de Martin Fowler donde señala que se debe considerar dependiente del contexto.

    
respondido por el Michael Borgwardt 29.03.2012 - 09:38
fuente
3

Esta es una llamada de juicio que realmente depende de su tamaño y escala anticipados de lo que está desarrollando. El enfoque más rígido es limitar los tipos de ORM a un componente de acceso a datos y usar POCO en una biblioteca común como tipos referenciados y utilizados por todas las capas. Esto permitiría una separación física futura así como una separación lógica. También podría decidir que debería existir una capa adicional entre la IU y la capa de lógica de negocios. Esto suele denominarse capa de interfaz o interfaz de negocios. Esta capa adicional es donde vive su "código de caso de uso". La capa Fachada / BI invoca el código acoplado de manera flexible (por ejemplo, la fachada tiene una función ProcessOrder () que llama a la lógica de negocios 1: M veces para realizar todos los pasos necesarios para procesar el pedido).

Sin embargo, dicho todo esto: muchas veces esta cantidad de arquitectura es simplemente una exageración innecesaria. Por ejemplo, código específico para un sitio web simple donde no tiene intención de empaquetar sus componentes para su reutilización. Es perfectamente válido crear un sitio web de MVC y usar objetos EF para este tipo de solución. Si el sitio necesita escalar más tarde, puede buscar en la agrupación en clúster o en un proceso que a menudo se pierde en una pelea llamada "refactorización".

    
respondido por el Sean Chase 29.03.2012 - 06:54
fuente
3

Solo recuérdele a su colega que no necesita arquitectar en exceso los modelos como si se tratara de un proyecto Java. Quiero decir, comparar dos objetos persistentes es un comportamiento, pero no está especificado por la capa de persistencia. Entonces, la pregunta de la cerveza 6 es: ¿por qué las clases que no tienen relación alguna describen algo sobre lo mismo? Claro, la persistencia es un aspecto suficientemente grande de un modelo que debe tratarse por separado, pero no lo suficiente como para garantizar que se trate de manera distinta a todo lo demás. Si maneja su automóvil, lo lava o lo rompe, manipula su automóvil todo el tiempo.

Entonces, ¿por qué no componer todos estos aspectos diferentes en una sola clase de modelo? Necesita un montón de métodos de clase que traten con objetos persistentes: póngalos en una clase; Usted tiene un montón de métodos de instancia relacionados con la validación, póngalos en otro. Por último, mezclar los dos en y ¡voilá! Te conseguiste una representación de modelo inteligente, autoconsciente y totalmente contenida allí mismo.

    
respondido por el Filip Dupanović 29.03.2012 - 09:00
fuente
1

Además de otras respuestas, preste atención a los ocultos ocultos cuando use modelos de dominio enriquecidos con un ORM.

Tuve problemas al inyectar servicios polimórficos en las clases del modelo persistente al intentar lograr algo como el siguiente pseudocódigo:

Person john = new Person('John Doe')
Organisation company = organisation_repository.find('some id')
Employee our_collegue_john = company.hire(john)

En este caso, una Organización puede requerir un HRService como una dependencia de constructor (por ejemplo). Por lo general, no puede controlar fácilmente la instanciación de sus clases modelo cuando utiliza un ORM.

Estaba usando Doctrine ORM y el contenedor de servicios de Symfony. Tuve que emparejar el ORM de una manera no tan elegante y no tuve más remedio que separar la persistencia y los modelos de negocio. No lo he intentado todavía con sqlachemy, pensó. Python podría ser más flexible que PHP para estas cosas.

    
respondido por el abstrus 18.01.2017 - 04:44
fuente

Lea otras preguntas en las etiquetas