¿Por qué necesitamos objetos de entidad? [cerrado]

139

Realmente necesito ver un debate honesto y reflexivo sobre los méritos del paradigma de diseño de aplicaciones empresariales actualmente aceptado .

No estoy convencido de que los objetos de entidad deberían existir.

Por objetos de entidad me refiero a las cosas típicas que tendemos a construir para nuestras aplicaciones, como "Persona", "Cuenta", "Orden", etc.

Mi filosofía de diseño actual es esta:

  • Todo el acceso a la base de datos debe realizarse mediante procedimientos almacenados.
  • Siempre que necesite datos, llame a un procedimiento almacenado e itere sobre un SqlDataReader o las filas en una DataTable

(Nota: también he creado aplicaciones empresariales con Java EE, amigos de Java, sustituyan el equivalente por mis ejemplos de .NET)

No soy anti-OO. Escribo muchas clases para diferentes propósitos, solo que no entidades. Admitiré que una gran parte de las clases que escribo son clases auxiliares estáticas.

No estoy construyendo juguetes. Estoy hablando de aplicaciones transaccionales grandes y de alto volumen implementadas en múltiples máquinas. Aplicaciones web, servicios de Windows, servicios web, interacción b2b, lo que sea.

He usado OR Mappers. He escrito algunos. He usado la pila Java EE, CSLA y algunos otros equivalentes. No solo los he usado, sino que desarrollé y mantuve activamente estas aplicaciones en entornos de producción.

He llegado a la conclusión de batalla probado que los objetos son cada entidad en nuestro camino, y nuestra vida sería así mucho más fácil sin ellos.

Considere este simple ejemplo: recibe una llamada de soporte sobre una determinada página de su aplicación que no funciona correctamente, tal vez uno de los campos no se persiste como debería ser. Con mi modelo, el desarrollador asignado para encontrar el problema abre exactamente 3 archivos . Un ASPX, un ASPX.CS y un archivo SQL con el procedimiento almacenado. El problema, que podría ser un parámetro faltante en la llamada al procedimiento almacenado, tarda minutos en resolverse. Pero con cualquier modelo de entidad, invariablemente activará el depurador, comenzará a recorrer el código y puede terminar con 15-20 archivos abiertos en Visual Studio. Cuando bajas al final de la pila, olvidaste dónde empezaste. Solo podemos mantener tantas cosas en nuestras cabezas al mismo tiempo. El software es increíblemente complejo sin agregar capas innecesarias.

La complejidad del desarrollo y la resolución de problemas son solo un lado de mi queja.

Ahora hablemos de escalabilidad.

¿Los desarrolladores se dan cuenta de que cada vez que escriben o modifican cualquier código que interactúa con la base de datos, necesitan hacer un análisis exhaustivo del impacto exacto en la base de datos? Y no solo la copia de desarrollo, me refiero a una imitación de producción, por lo que puede ver que la columna adicional que ahora necesita para su objeto acaba de invalidar el plan de consulta actual y un informe que se ejecutó en 1 segundo ahora tomará 2 minutos, solo porque agregaste una sola columna a la lista de selección? ¿Y resulta que el índice que necesita ahora es tan grande que el DBA tendrá que modificar el diseño físico de sus archivos?

Si deja que las personas se alejen demasiado del almacén de datos físicos con una abstracción, crearán estragos con una aplicación que necesita escalar.

No soy un fanático. Puedo estar convencido si estoy equivocado, y tal vez lo estoy, ya que hay un fuerte impulso hacia Linq hacia Sql, ADO.NET EF, Hibernate, Java EE, etc. Por favor, piense en sus respuestas, si me falta algo Realmente quiero saber qué es y por qué debería cambiar mi forma de pensar.

[Editar]

Parece que esta pregunta vuelve a estar activa de repente, así que ahora que tenemos la nueva función de comentarios, he comentado directamente sobre varias respuestas. Gracias por las respuestas, creo que esta es una discusión saludable.

Probablemente debería haber sido más claro que estoy hablando de aplicaciones empresariales. Realmente no puedo comentar, por ejemplo, un juego que se ejecuta en el escritorio de alguien o una aplicación móvil.

Una cosa que tengo que poner aquí en la parte superior en respuesta a varias respuestas similares: la ortogonalidad y la separación de las preocupaciones a menudo se mencionan como razones para ir entidad / ORM. Los procedimientos almacenados, para mí, son el mejor ejemplo de separación de preocupaciones que se me ocurre. Si no permite cualquier otro acceso a la base de datos, que no sea a través de procedimientos almacenados, en teoría podría rediseñar todo su modelo de datos y no romper ningún código, siempre y cuando mantenga las entradas y salidas de los procedimientos almacenados. Son un ejemplo perfecto de programación por contrato (siempre que evite "seleccionar *" y documente los conjuntos de resultados).

Pregúntele a alguien que ha estado en la industria durante mucho tiempo y que ha trabajado con aplicaciones de larga duración: ¿cuántas capas de aplicaciones y UI han aparecido y desaparecido mientras una base de datos ha sobrevivido? ¿Qué tan difícil es ajustar y refactorizar una base de datos cuando hay 4 o 5 capas de persistencia diferentes que generan SQL para obtener los datos? ¡No puedes cambiar nada! Los ORM o cualquier código que genere SQL bloquean su base de datos en piedra .

Eric Z Beard
fuente
Después de leer su pregunta, nos parecemos mucho, y me he preguntado exactamente lo mismo durante años (desde que escuché sobre los marcos de entidades de terceros y ahora de Microsoft)
pearcewg 03 de
1
¿Está diciendo que la lógica de negocios son los objetos auxiliares, o en los procesos almacenados? Le pregunto a muchas personas que parecen pensar que usted está diciendo lo siguiente ... pero lo que creo que está diciendo es que todavía tiene lógica comercial en los objetos codificados, solo está obteniendo datos directamente de la base de datos y utilizando esos datos , en lugar de un ORM o asignación a objetos especializados para contener los datos. Tiendo a sentir lo mismo, pero también estoy evaluando EF4 para ver si podría valer la pena.
alquímico
"Los consumidores innovadores son a menudo los que se atornillan". - alguien con experiencia
Uğur Gümüşhan
Heredé un sistema con más de 2500 SPROC donde la aplicación se ve simplemente como un medio para activar SPROC y dar sentido a su salida. Cada dato de lectura y escritura tiene su propio SPROC. No hay puntos centrales de control. Es horrible y casi tan maleable como el granito. Considero optimizar las bases de datos. Los 2500 SPROCS me pusieron en mi lugar. En comparación con un sistema con una capa de dominio bien organizada y un código DAL reutilizable, parece mal concebido y es una pesadilla de soporte. Las tareas simples toman horas y destruyen el alma. Los SPROC deben usarse para cargas altas o métodos especiales IMO
trucker_jim
Sobre su ejemplo de "depuración": con las pruebas unitarias, sabría mucho más rápidamente dónde van las cosas mal.
MarioDS

Respuestas:

59

Creo que todo se reduce a lo complicada que es la "lógica" de la aplicación y dónde la ha implementado. Si toda su lógica está en procedimientos almacenados, y todo lo que su aplicación hace es llamar a esos procedimientos y mostrar los resultados, entonces desarrollar objetos de entidad es realmente una pérdida de tiempo. Pero para una aplicación donde los objetos tienen interacciones ricas entre sí, y la base de datos es solo un mecanismo de persistencia, puede tener valor tener esos objetos.

Entonces, diría que no hay una respuesta única para todos. Los desarrolladores deben ser conscientes de que, a veces, tratar de ser demasiado OO puede causar más problemas de los que resuelve.

Kristopher Johnson
fuente
Kristopher parece que resucitaste esta pregunta al vincularla con otra pregunta. Me pregunto qué quiere decir con "interacciones ricas", y cómo sería poco práctico implementarlas sin objetos.
Eric Z Beard el
44
Todo lo que se puede hacer con objetos también se puede hacer sin objetos. Creo que el diseño OO suele ser mucho más fácil que los métodos que no son OO para hacer algo "complicado", pero entiendo que no funciona para todos.
Kristopher Johnson
Estoy de acuerdo: la respuesta de "cuándo usar objetos" depende de si las propiedades de los objetos pueden requerir acciones o cambios en la lógica empresarial. Por ejemplo, las instancias de Usuario o Persona pueden tener Contraseña y Nombre de inicio de sesión -> sus acciones de código cambian de acuerdo a cuáles son los valores en ellas. Por el contrario, si tuviera un Producto, tendría que mostrar (nada más, ninguna otra acción) que obtener un DataSet de db y simplemente construir la GUI.
Yordan Georgiev
55
Hay un equilibrio Evita la religión y elige lo que funciona.
Jeff Davis
27

La teoría dice que las implementaciones altamente cohesivas y poco acopladas son el camino a seguir.

Así que supongo que está cuestionando ese enfoque, es decir, separar las preocupaciones.

¿Debería mi archivo aspx.cs interactuar con la base de datos, llamar a un sproc y comprender IDataReader?

En un entorno de equipo, especialmente donde hay personas menos técnicas que se ocupan de la porción aspx de la aplicación, no necesito que estas personas puedan "tocar" estas cosas.

Separar mi dominio de mi base de datos me protege de los cambios estructurales en la base de datos, ¿seguramente algo bueno? La eficacia de la base de datos es absolutamente importante, así que deje que alguien que sea excelente en esas cosas se ocupe de esas cosas, en un lugar, con el menor impacto posible en el resto del sistema.

A menos que esté malinterpretando su enfoque, un cambio estructural en la base de datos podría tener un gran área de impacto con la superficie de su aplicación. Veo que esta separación de preocupaciones nos permite a mí y a mi equipo minimizar esto. Además, cualquier miembro nuevo del equipo debería comprender mejor este enfoque.

Además, ¿su enfoque parece abogar por la lógica empresarial de su aplicación para residir en su base de datos? Esto me parece incorrecto, SQL es realmente bueno para consultar datos y, en mi opinión, no expresa lógica empresarial.

Sin embargo, un pensamiento interesante, aunque se siente a un paso de SQL en el aspx, que desde mis viejos días de asp no estructurados, me llena de temor.

revs nachojammers
fuente
Estoy de acuerdo en que tener un montón de SQL dinámico esparcido por todo el código subyacente es malo. Tienes que mantener las llamadas Db claras y distintas. El ajuste de las llamadas sproc en métodos auxiliares estáticos logra una especie de separación sin tener que recorrer la ruta ORM.
Eric Z Beard el
1
Aunque nunca he trabajado en un entorno asp, estoy seguro de que algunas de las personas menos técnicas te dejarán boquiabierto con algún código javascript del lado del cliente, lo que resulta en una hermosa experiencia de usuario, independientemente de cualquier interfaz mala para la parte posterior técnica -final.
crowne
Estoy de acuerdo con usted aquí y he sabido que también hago algunos javascript del lado del cliente, lo que resultó en una experiencia de usuario no muy mala, incluso si lo digo yo mismo. Sin embargo, me gustaría pensar que las interfaces de fondo no son malas y que los programadores del lado del cliente no tienen que preocuparse por nada de eso, porque he intentado separar mis preocupaciones.
nachojammers
2
"Esto me parece incorrecto, SQL es realmente bueno para consultar datos y, en mi opinión, no expresa la lógica empresarial". - A menos que use, digamos, PL / SQL, que agrega un lenguaje de programación rico además de (y estrechamente integrado con) el SQL, y su código se almacena dentro de la base de datos. Aumenta el rendimiento al evitar los viajes de ida y vuelta a la red. Y encapsula su lógica empresarial independientemente de qué cliente se conecte a la base de datos.
ObiWanKenobi
25

Una razón: separar su modelo de dominio de su modelo de base de datos.

Lo que hago es usar Test Driven Development, así que primero escribo mis capas de UI y Modelo y la capa de Datos se burla, por lo que la UI y el modelo se construyen alrededor de objetos específicos del dominio, luego mapeo estos objetos a la tecnología que estoy usando la capa de datos. Es una mala idea dejar que la estructura de la base de datos determine el diseño de su aplicación. Siempre que sea posible, escriba primero la aplicación y deje que eso influya en la estructura de su base de datos, no al revés.

Dan
fuente
9
Tengo que decir que realmente no estoy de acuerdo, al menos para las aplicaciones empresariales. Los datos son la aplicación.
Eric Z Beard el
3
¿por qué querrías tener dos modelos separados de los mismos datos?
Seun Osewa
3
Porque para algunos propósitos, una interpretación del modelo puede ser más adecuada. Alguna lógica funciona mucho mejor en objetos que en filas.
Wouter Lievens
1
Creo que es una buena idea mal implementada.
Jeff Davis el
21

Para mí, todo se reduce a que no quiero que mi aplicación se preocupe por cómo se almacenan los datos. Probablemente me abofetearán por decir esto ... pero su aplicación no son sus datos, los datos son un artefacto de la aplicación. Quiero que mi aplicación esté pensando en términos de Clientes, Pedidos y Artículos, no en una tecnología como DataSets, DataTables y DataRows ... porque quién sabe cuánto tiempo durarán.

Estoy de acuerdo en que siempre hay una cierta cantidad de acoplamiento, pero prefiero que el acoplamiento llegue hacia arriba en lugar de hacia abajo. Puedo ajustar las ramas y las hojas de un árbol más fácilmente de lo que puedo alterar su tronco.

Tiendo a reservar sprocs para informar, ya que las consultas tienden a ser un poco más desagradables que el acceso a los datos generales de las aplicaciones.

También tiendo a pensar que con una prueba de unidad adecuada desde el principio, es probable que esa columna no persista no sea un problema.

Webjedi
fuente
3
"su aplicación no son sus datos, los datos son un artefacto de la aplicación". - La aplicación no tiene valor sin los datos. Los datos tienen un gran valor sin la aplicación. Las aplicaciones van y vienen (se reescriben) todo el tiempo, los datos en cualquier aplicación no trivial siempre se mantienen. Y el modelo de datos permanece sorprendentemente estable en el tiempo.
ObiWanKenobi
16

Eric, estás muerto. Para cualquier aplicación realmente escalable / fácil de mantener / robusta, la única respuesta real es prescindir de toda la basura y atenerse a lo básico.

He seguido una trayectoria similar con mi carrera y he llegado a las mismas conclusiones. Por supuesto, somos considerados herejes y vistos graciosos. Pero mis cosas funcionan y funcionan bien.

Cada línea de código debe considerarse con recelo.

Yo no
fuente
2
Seguro, lo hace sin duda funciona bien cuando tienes un montón de personal anjd recursos, pero creo que si usted es un equipo de un solo hombre piensa "nuevas" técnicas pueden ayudar mucho ..
Carl Hörberg
10

Me gustaría responder con un ejemplo similar al que usted propuso.

En mi empresa, tuve que crear una sección CRUD simple para productos, construí todas mis entidades y un DAL por separado. Más tarde, otro desarrollador tuvo que cambiar una tabla relacionada e incluso cambió el nombre de varios campos. El único archivo que tuve que cambiar para actualizar mi formulario fue el DAL para esa tabla.

Lo que (en mi opinión) las entidades aporta a un proyecto es:

Ortogonalidad: los cambios en una capa pueden no afectar a otras capas (por supuesto, si realiza un gran cambio en la base de datos, se extenderá por todas las capas, pero la mayoría de los pequeños cambios no lo harán).

Capacidad de prueba: puede probar su lógica sin tocar su base de datos. Esto aumenta el rendimiento en sus pruebas (lo que le permite ejecutarlas con más frecuencia).

Separación de preocupaciones: en un gran producto, puede asignar la base de datos a un DBA y él puede optimizarlo al máximo. Asigne el modelo a un experto en negocios que tenga los conocimientos necesarios para diseñarlo. Asigne formularios individuales a desarrolladores con más experiencia en formularios web, etc.

Finalmente, me gustaría agregar que la mayoría de los mapeadores de ORM admiten procedimientos almacenados, ya que eso es lo que está utilizando.

Salud.

Julio Cesar
fuente
2
Los procedimientos almacenados son probablemente el mejor ejemplo de ortogonalidad y separación de preocupaciones. Si se usan correctamente, encapsulan completamente la base de datos.
Eric Z Beard el
1
@Eric Z Beard: Sí, pero ¿cómo puede escribir pruebas unitarias en torno a procedimientos almacenados mientras aísla solo la lógica dentro del procedimiento almacenado? Los procedimientos almacenados están estrechamente acoplados a la base de datos, y a la mayoría de nosotros los tipos de ORM no nos gusta. Para escribir una prueba unitaria para un procedimiento almacenado, necesitaría confiar en ciertos datos para estar en la base de datos. y no puede volver a ejecutar esta prueba una y otra vez sin esa dependencia de datos. Esa prueba que escribiría ya no sería una prueba unitaria, sino que sería una Prueba de integración.
7wp
8

Creo que puede estar "mordiendo más de lo que puede masticar" sobre este tema. Ted Neward no estaba siendo impertinente cuando lo llamó el " Vietnam de la informática ".

Una cosa que puedo garantizar absolutamente es que cambiará el punto de vista de nadie sobre el asunto, como se ha demostrado con frecuencia en innumerables otros blogs, foros, podcasts, etc.

Ciertamente está bien tener una discusión abierta y debatir sobre un tema controvertido, es solo que este se ha hecho tantas veces que ambas "partes" han acordado estar en desacuerdo y simplemente continuaron escribiendo software.

Si desea leer más en ambos lados, vea los artículos en el blog de Ted, Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans, etc.

Ashley Henderson
fuente
1
Tienes razón, la mayoría de la gente no cambiará sus opiniones. Me doy cuenta de que se supone que el enfoque de Stack Overflow son preguntas objetivas, ¡pero las subjetivas son mucho más divertidas! Personalmente, he aprendido mucho de esta discusión.
Eric Z Beard el
Creo que los diversos enfoques son específicos del contexto y que esta discusión puede servir para desambiguar qué escenarios se benefician o disminuyen de los diferentes modelos de persistencia. Los expertos en el tema no cambiarán sus opiniones rápidamente, pero este es un sitio de preguntas donde las personas buscan la experiencia de otros.
TheXenocide
Guau. +1 para el enlace al artículo "Vietnam of Computer Science" que tiene una excelente introducción al tema de ORM versus no ORM.
lambacck
7

@ Dan, lo siento, ese no es el tipo de cosas que estoy buscando. Conozco la teoría Su afirmación "es una muy mala idea" no está respaldada por un ejemplo real. Estamos tratando de desarrollar software en menos tiempo, con menos personas, con menos errores, y queremos la capacidad de realizar cambios fácilmente. Su modelo de múltiples capas, en mi experiencia, es negativo en todas las categorías anteriores. Especialmente con respecto a hacer que el modelo de datos sea lo último que haga. El modelo de datos físicos debe ser una consideración importante desde el día 1.

Eric Z Beard
fuente
wow, alguien más que piensa como yo en esto ... mis aplicaciones casi siempre tratan de la manipulación de datos, eso es lo que realmente hacen.
alquímico
Esto sería mejor como un comentario ahora que esas funciones están disponibles
Casebash
1
Perdóname por ser pedante, pero como esta es una pregunta popular y el error que cometiste es común, sentí que debería señalarlo. "Menos tiempo" es correcto, pero "menos personas" y "menos errores" deberían ser "menos personas" y "menos errores". Si tiene menos harina, puede hacer menos galletas. (Además, si usa demasiada harina, hará demasiadas galletas, una distinción que se olvida con menos frecuencia). De nuevo, mis disculpas; Solo trato de ser útil.
WCWedin
4

Tu pregunta me pareció realmente interesante.
Por lo general, necesito objetos de entidades para encapsular la lógica de negocios de una aplicación. Sería realmente complicado e inadecuado introducir esta lógica en la capa de datos.
¿Qué harías para evitar estos objetos de entidades? ¿Qué solución tienes en mente?

jdecuyper
fuente
Esto sería mejor como comentario
Casebash el
4

Los objetos de entidad pueden facilitar el almacenamiento en caché en la capa de aplicación. Buena suerte almacenando en caché un lector de datos.

FlySwat
fuente
4

También deberíamos hablar sobre la noción de lo que realmente son las entidades. Cuando leo esta discusión, tengo la impresión de que la mayoría de las personas aquí están mirando entidades en el sentido de un Modelo de Dominio Anémico . ¡Mucha gente está considerando el modelo de dominio anémico como un antipatrón!

Hay valor en los modelos de dominio rico. De eso se trata Domain Driven Design . Personalmente, creo que OO es una forma de conquistar la complejidad. Esto significa no solo complejidad técnica (como acceso a datos, enlace de interfaz de usuario, seguridad ...) sino también complejidad en el dominio empresarial .

Si podemos aplicar técnicas OO para analizar, modelar, diseñar e implementar nuestros problemas comerciales, ¡esta es una gran ventaja para el mantenimiento y la extensibilidad de aplicaciones no triviales!

Hay diferencias entre sus entidades y sus tablas. Las entidades deben representar su modelo, ¡las tablas solo representan el aspecto de datos de su modelo!

Es cierto que los datos duran más que las aplicaciones, pero considere esta cita de David Laribee : los modelos son para siempre ... los datos son un efecto secundario feliz.

Algunos enlaces más sobre este tema:

jbandi
fuente
1
Francamente, estoy empezando a creer que los datos duran más que el software que los rodea, porque a menudo se presta muy poca atención al diseño del software junto con una verdadera comprensión del negocio.
flq
4

Pregunta realmente interesante. Honestamente, no puedo demostrar por qué las entidades son buenas. Pero puedo compartir mi opinión de por qué me gustan. Código como

void exportOrder(Order order, String fileName){...};

no le preocupa de dónde provino el pedido: de DB, de solicitud web, de prueba unitaria, etc. Hace que este método declare más explícitamente qué es exactamente lo que requiere, en lugar de tomar DataRow y documentar qué columnas espera tener y qué tipos deberían ser. Lo mismo se aplica si lo implementa de alguna manera como procedimiento almacenado: aún debe insertar la identificación de registro, aunque no necesariamente debe estar presente en la base de datos.

La implementación de este método se haría en función de la abstracción de la orden, no en función de cómo se presenta exactamente en DB. La mayoría de las operaciones que implementé realmente no dependen de cómo se almacenan estos datos. Entiendo que algunas operaciones requieren el acoplamiento con la estructura de DB para fines de rendimiento y escalabilidad, solo en mi experiencia no hay demasiadas. En mi experiencia, a menudo es suficiente saber que Person tiene .getFirstName () que devuelve String, y .getAddress () que devuelve Address, y address tiene .getZipCode (), etc., y no me importa qué tablas se invocan para almacenar esos datos .

Si tiene que lidiar con los problemas que describió, como cuando los saltos de columna adicionales informan el rendimiento, entonces para sus tareas, la base de datos es una parte crítica, y de hecho debe estar lo más cerca posible de ella. Si bien las entidades pueden proporcionar algunas abstracciones convenientes, también pueden ocultar algunos detalles importantes.

La escalabilidad es un punto interesante aquí: la mayoría de los sitios web que requieren una escalabilidad enorme (como facebook, livejournal, flickr) tienden a usar el enfoque DB-ascético, cuando DB se usa lo más raro posible y los problemas de escalabilidad se resuelven mediante el almacenamiento en caché, especialmente mediante el uso de RAM. http://highscalability.com/ tiene algunos artículos interesantes al respecto.

Pavel Feldman
fuente
2
La escalabilidad en las aplicaciones empresariales a menudo no se puede resolver mediante el almacenamiento en caché, ya que gran parte de ella cambia con frecuencia los datos transaccionales en tablas con millones de filas. Veo facebook et. Alabama. como sitios web de alto volumen, donde la parte difícil es atender tantas solicitudes web.
Eric Z Beard
4

Hay otras buenas razones para los objetos de entidad además de la abstracción y el acoplamiento flojo. Una de las cosas que más me gustan es la escritura fuerte que no se puede obtener con un DataReader o un DataTable. Otra razón es que, cuando se hace bien, las clases de entidad adecuadas pueden hacer que el código sea más fácil de mantener mediante el uso de construcciones de primera clase para términos específicos de dominio que cualquiera que vea el código probablemente entienda en lugar de un montón de cadenas con nombres de campo utilizados para indexar un DataRow. Los procedimientos almacenados son realmente ortogonales al uso de un ORM ya que muchos marcos de mapeo le dan la posibilidad de mapear a sprocs.

No consideraría sprocs + datareaders un sustituto de un buen ORM. Con los procedimientos almacenados, todavía está limitado y estrechamente vinculado a la firma de tipo del procedimiento, que utiliza un sistema de tipo diferente al código de llamada. Los procedimientos almacenados pueden estar sujetos a modificaciones para acomodar opciones adicionales y cambios de esquema. Una alternativa a los procedimientos almacenados en el caso de que el esquema esté sujeto a cambios es usar vistas: puede asignar objetos a vistas y luego volver a asignar vistas a las tablas subyacentes cuando las cambia.

Puedo entender su aversión a los ORM si su experiencia consiste principalmente en Java EE y CSLA. Es posible que desee echar un vistazo a LINQ to SQL, que es un marco muy liviano y es principalmente un mapeo uno a uno con las tablas de la base de datos, pero generalmente solo necesita una extensión menor para que sean objetos comerciales completos. LINQ to SQL también puede asignar objetos de entrada y salida a parámetros y resultados de procedimientos almacenados.

El marco de la entidad ADO.NET tiene la ventaja adicional de que las tablas de la base de datos pueden verse como clases de entidad que se heredan entre sí, o como columnas de varias tablas agregadas en una sola entidad. Si necesita cambiar el esquema, puede cambiar la asignación del modelo conceptual al esquema de almacenamiento sin cambiar el código de aplicación real. Y nuevamente, los procedimientos almacenados se pueden usar aquí.

Creo que fallan más proyectos de TI en las empresas debido a la imposibilidad de mantener el código o la baja productividad del desarrollador (que puede suceder, por ejemplo, por el cambio de contexto entre la escritura sproc y la escritura de aplicaciones) que los problemas de escalabilidad de una aplicación.

Mark Cidade
fuente
Creo que un buen compromiso sería mapear un ORM a procedimientos almacenados, excepto que esto puede hacerse fácilmente mal: si solo crea los 4 procesos CRUD para cada tabla, no ha logrado nada. ¿Puede asignar procesos grandes y de grano grueso a entidades, o eso realmente no lo lleva a ninguna parte?
Eric Z Beard el
Además de las operaciones CRUD, los ORM de Microsoft le permiten agregar métodos a las clases de entidad que se asignan directamente a cualquier proceso almacenado que desee lanzar (siempre que todos los tipos de entrada / salida sean asignables).
Mark Cidade
3

También me gustaría agregar a la respuesta de Dan que separar ambos modelos podría permitir que su aplicación se ejecute en diferentes servidores de bases de datos o incluso en modelos de bases de datos.

revs Lars Truijens
fuente
3

¿Qué sucede si necesita escalar su aplicación equilibrando la carga de más de un servidor web? Puede instalar la aplicación completa en todos los servidores web, pero una mejor solución es hacer que los servidores web hablen con un servidor de aplicaciones.

Pero si no hay objetos de entidad, no tendrán mucho de qué hablar.

No digo que no deba escribir monolitos si es una aplicación simple, interna y de corta duración. Pero tan pronto como se vuelva moderadamente complejo, o deba durar una cantidad significativa de tiempo, realmente necesita pensar en un buen diseño.

Esto ahorra tiempo a la hora de mantenerlo.

Al dividir la lógica de la aplicación de la lógica de presentación y el acceso a los datos, y al pasar DTO entre ellos, los desacopla. Permitiéndoles cambiar de forma independiente.

tgmdbm
fuente
3
Mucha gente está sacando el desacoplamiento y permitiendo que una capa cambie sin afectar a la otra. ¡Los procedimientos almacenados hacen esto mejor que cualquier ORM! Puedo alterar radicalmente el modelo de datos, y mientras los procedimientos devuelvan los mismos datos, nada se rompe.
Eric Z Beard el
2
En mi opinión, los procedimientos almacenados Y un modelo de entidad no son mutuamente excluyentes. Los procedimientos almacenados pueden proporcionar un mecanismo para almacenar su modelo de entidad. La pregunta es: ¿Su lógica de negocios funciona con las entidades o accede directamente a los procedimientos almacenados?
jbandi
3

Puede encontrar esta publicación en comp.object interesante.

No pretendo estar de acuerdo o en desacuerdo, pero es interesante y (creo) relevante para este tema.

Hamish Smith
fuente
Esa es una gran publicación. Resume mis pensamientos sobre ORM casi a la perfección.
Eric Z Beard
3

Una pregunta: ¿Cómo maneja las aplicaciones desconectadas si toda su lógica de negocios está atrapada en la base de datos?

En el tipo de aplicación Enterprise que me interesa, tenemos que tratar con varios sitios, algunos de ellos deben poder funcionar en un estado desconectado.
Si su lógica de negocios está encapsulada en una capa de Dominio que es fácil de incorporar en varios tipos de aplicaciones, por ejemplo dll, entonces puedo crear aplicaciones que conozcan las reglas de negocios y puedan, cuando sea necesario, aplicarlas localmente.

Para mantener la capa de dominio en los procedimientos almacenados en la base de datos, debe seguir con un solo tipo de aplicación que necesita una línea de visión permanente a la base de datos.

Está bien para una determinada clase de entornos, pero ciertamente no cubre todo el espectro de aplicaciones empresariales .

Renaud Bompuis
fuente
2

@jdecuyper, una máxima que me repito a menudo es "si la lógica de su negocio no está en su base de datos, es solo una recomendación". Creo que Paul Nielson dijo eso en uno de sus libros. Las capas de aplicaciones y la interfaz de usuario van y vienen, pero los datos generalmente duran mucho tiempo.

¿Cómo evito los objetos de entidad? Procedimientos almacenados en su mayoría. También admito libremente que la lógica de negocios tiende a llegar a través de todas las capas de una aplicación, lo intente o no. Una cierta cantidad de acoplamiento es inherente e inevitable.

Eric Z Beard
fuente
Estoy de acuerdo, la lógica de negocios que se encuentra en la aplicación a menudo no tiene en cuenta las otras formas en que los datos se pueden ingresar, eliminar o cambiar. Esto generalmente causa problemas de integridad de datos en el camino.
HLGEM
Y por qué siempre debe usar una capa de servicio para manejar la falta de coincidencia entre el mundo de los objetos y el mundo relacional. La lógica de negocios que fluye a cada capa ciertamente no es inevitable.
cdaq
2

He estado pensando mucho en esto mismo últimamente; Fui un gran usuario de CSLA por un tiempo, y me encanta la pureza de decir que "toda su lógica comercial (o al menos tanto como sea razonablemente posible) está encapsulada en entidades comerciales".

He visto que el modelo de entidad comercial proporciona un gran valor en los casos en que el diseño de la base de datos es diferente de la forma en que trabaja con los datos, como es el caso en una gran cantidad de software comercial.

Por ejemplo, la idea de un "cliente" puede consistir en un registro principal en una tabla de Clientes, combinado con todos los pedidos que el cliente ha realizado, así como todos los empleados del cliente y su información de contacto, y algunas de las propiedades de un cliente y sus hijos pueden determinarse a partir de tablas de búsqueda. Es realmente agradable desde el punto de vista del desarrollo poder trabajar con el Cliente como una entidad única, ya que desde una perspectiva comercial, el concepto de Cliente contiene todas estas cosas, y las relaciones pueden o no aplicarse en la base de datos.

Si bien agradezco la cita de que "si su regla empresarial no está en su base de datos, es solo una sugerencia", también creo que no debe diseñar la base de datos para hacer cumplir las reglas comerciales, debe diseñarla para que sea eficiente, rápida y normalizada .

Dicho esto, como otros han señalado anteriormente, no existe un "diseño perfecto", la herramienta tiene que adaptarse al trabajo. Pero el uso de entidades comerciales realmente puede ayudar con el mantenimiento y la productividad, ya que sabe a dónde ir para modificar la lógica empresarial, y los objetos pueden modelar conceptos del mundo real de una manera intuitiva.

Guy Starbuck
fuente
2

Eric

Nadie le impide elegir el marco / enfoque que desearía. Si va a ir por el camino "impulsado por datos / procedimiento almacenado", entonces, por todos los medios, ¡adelante! Especialmente si realmente le ayuda a entregar sus aplicaciones según las especificaciones y a tiempo.

La advertencia es (una otra cara de su pregunta), TODAS sus reglas comerciales deben estar en procedimientos almacenados, y su aplicación no es más que un cliente ligero.

Dicho esto, se aplican las mismas reglas si realiza su solicitud en OOP: sea coherente. Siga los principios de OOP, y eso incluye crear objetos de entidad para representar sus modelos de dominio.

La única regla real aquí es la consistencia de la palabra . Nadie te impide que te centres en DB. Nadie te impide hacer programas estructurados de la vieja escuela (también conocidos como funcionales / de procedimiento). Demonios, nadie impide que nadie haga código COBOL. PERO una aplicación tiene que ser muy, muy consistente una vez que se sigue este camino, si desea alcanzar algún grado de éxito.

Jon Limjap
fuente
Estoy de acuerdo con la coherencia en toda la aplicación. Para ser honesto, cambié las instrucciones de mi proyecto actual hace un tiempo y nunca pude arreglar el 100% del modelo original, lo que hace que las cosas sean confusas. Las mejores decisiones se toman mejor temprano.
Eric Z Beard el
Eric, cierto en verdad. Una vez fui fanático de OOP (como parecen ser otros en este hilo) pero conocí a un tipo que posee una compañía que tiene mucho éxito vendiendo aplicaciones basadas en DB. Eso sacudió mi mundo. Todavía soy un fanático de OOP / TDD, pero ya no frunzo el ceño centrado en DB.
Jon Limjap
El problema es que a veces las personas venden en exceso su ideología, potencialmente podría ganarse la vida vendiendo sitios solo en html y javascript, si tuviera una buena metodología para eliminarlos.
Mark Rogers
2

Realmente no estoy seguro de lo que consideras "Aplicaciones empresariales". Pero tengo la impresión de que lo está definiendo como una aplicación interna donde el RDBMS se establecería en piedra y el sistema no tendría que ser interoperable con ningún otro sistema, ya sea interno o externo.

Pero, ¿qué pasaría si tuviera una base de datos con 100 tablas que equivalen a 4 procedimientos almacenados para cada tabla solo para operaciones CRUD básicas que son 400 procedimientos almacenados que deben mantenerse y no están fuertemente tipados, por lo que son susceptibles a errores tipográficos y no pueden ser probados por unidades . ¿Qué sucede cuando obtienes un nuevo CTO que es un evangelista de código abierto y quiere cambiar el RDBMS de SQL Server a MySql?

Una gran cantidad de software hoy en día, ya sea que las aplicaciones o productos empresariales estén utilizando SOA y tengan algunos requisitos para exponer los servicios web, al menos el software con el que estoy y he estado involucrado. Usando su enfoque, terminaría exponiendo una DataTable serializada o DataRows. Ahora esto puede considerarse aceptable si se garantiza que el Cliente sea .NET y en una red interna. Pero cuando no se conoce el Cliente, debe esforzarse por diseñar una API que sea intuitiva y, en la mayoría de los casos, no desearía exponer el esquema de la base de datos completa. Ciertamente no quisiera explicarle a un desarrollador de Java qué es un DataTable y cómo usarlo. También se considera el ancho de banda y el tamaño de la carga útil y las tablas de datos serializadas, los conjuntos de datos son muy pesados.

No hay una bala de plata con el diseño del software y realmente depende de dónde radiquen las prioridades, para mí está en el código de prueba de la unidad y los componentes acoplados libremente que pueden ser fácilmente consumidos por cualquier cliente.

solo mis 2 centavos

usuario17060
fuente
No, mi definición de aplicación empresarial es lo contrario. El esquema cambia a menudo, y hay muchas aplicaciones que usan la base de datos, e interopera con muchos socios externos. En una aplicación empresarial real , nunca, nunca, cambiarás a un RDBMS diferente. Simplemente no sucede.
Eric Z Beard
Y crear 4 procs para cada tabla es una mala práctica. Lo acopla estrechamente al modelo de datos al igual que SQL generado a partir de un ORM, por lo que no le compra nada. Los procesos deben ser operaciones comerciales de grano grueso, no solo CRUD en cada tabla.
Eric Z Beard
Pero, ¿no es esta la respuesta ?: cuanto más código necesite escribir, más características necesitará para soporte de programación a gran escala: encapsulación, tipeado de cadenas, refactorización, estilo sofisticado y verificación de errores, etc .; Java y .NET tienen una gran cantidad de soporte en esta área, los lenguajes de procedimientos almacenados no.
reinierpost 01 de
2

Me gustaría ofrecer otro ángulo al problema de la distancia entre OO y RDB: historia.

Cualquier software tiene un modelo de realidad que es hasta cierto punto una abstracción de la realidad. Ningún programa de computadora puede capturar todas las complejidades de la realidad, y los programas se escriben solo para resolver un conjunto de problemas de la realidad. Por lo tanto, cualquier modelo de software es una reducción de la realidad. A veces, el modelo de software obliga a la realidad a reducirse. Como cuando desea que la compañía de alquiler de automóviles le reserve un automóvil siempre que sea azul y tenga aleaciones, pero el operador no puede cumplir porque su solicitud no cabe en la computadora.

RDB proviene de una muy antigua tradición de poner información en tablas, llamada contabilidad. La contabilidad se hizo en papel, luego en tarjetas perforadas, luego en computadoras. Pero la contabilidad ya es una reducción de la realidad. La contabilidad ha obligado a las personas a seguir su sistema tanto tiempo que se ha convertido en una realidad aceptada. Es por eso que es relativamente fácil hacer software de computadora para contabilidad, la contabilidad ha tenido su modelo de información, mucho antes de que apareciera la computadora.

Dada la importancia de los buenos sistemas de contabilidad y la aceptación que obtiene de cualquier gerente comercial, estos sistemas se han vuelto muy avanzados. Las bases de la base de datos ahora son muy sólidas y nadie duda en mantener los datos vitales en algo tan confiable.

Supongo que OO debe haber aparecido cuando la gente ha descubierto que otros aspectos de la realidad son más difíciles de modelar que la contabilidad (que ya es un modelo). OO se ha convertido en una idea muy exitosa, pero la persistencia de los datos de OO está relativamente poco desarrollada. RDB / Contabilidad ha tenido victorias fáciles, pero OO es un campo mucho más grande (básicamente todo lo que no es contabilidad).

Muchos de nosotros hemos querido usar OO pero aún queremos un almacenamiento seguro de nuestros datos. ¿Qué puede ser más seguro que almacenar nuestros datos de la misma manera que lo hace el estimado sistema de contabilidad? Es una perspectiva atractiva, pero todos nos encontramos con las mismas trampas. Muy pocos se han tomado la molestia de pensar en la persistencia de OO en comparación con los esfuerzos masivos de la industria RDB, que ha tenido el beneficio de la tradición y la posición de la contabilidad.

Prevayler y db4o son algunas sugerencias, estoy seguro de que hay otras de las que no he oído hablar, pero ninguna parece haber recibido la mitad de la prensa como, por ejemplo, hibernación.

Almacenar sus objetos en buenos archivos antiguos ni siquiera parece ser tomado en serio para las aplicaciones multiusuario, y especialmente las aplicaciones web.

En mi lucha diaria para cerrar el abismo entre OO y RDB, uso OO tanto como sea posible, pero trato de mantener la herencia al mínimo. No suelo usar SP. Usaré las consultas avanzadas solo en aspectos que parecen contables.

Seré felizmente sorprendido cuando el abismo se cierre definitivamente. Creo que la solución llegará cuando Oracle lance algo así como "Oracle Object Instance Base". Para realmente ponerse al día, tendrá que tener un nombre tranquilizador.

Guge
fuente
No creo que necesite ORM para que OO se considere útil. Uso procs almacenados y escribo muchas clases auxiliares estáticas en mi código, pero esas clases se basan en el enorme marco .NET, que es una fantástica colección de objetos.
Eric Z Beard
Tu lógica tiene sentido, pero no creo que la premisa sea sólida. Nunca he oído hablar de nada que no pueda ser mapeado con RDB.
Jeff Davis el
1

No mucho tiempo en este momento, pero justo fuera de mi cabeza ...

El modelo de entidad le permite proporcionar una interfaz consistente a la base de datos (y otros sistemas posibles) incluso más allá de lo que puede hacer una interfaz de procedimiento almacenado. Mediante el uso de modelos empresariales para toda la empresa, puede asegurarse de que todas las aplicaciones afecten los datos de manera consistente, lo cual es algo MUY importante. De lo contrario, terminas con malos datos, lo cual es simplemente malvado.

Si solo tiene una aplicación, entonces realmente no tiene un sistema "empresarial", independientemente de cuán grande sea esa aplicación o sus datos. En ese caso, puede utilizar un enfoque similar al que habla. Solo tenga en cuenta el trabajo que se necesitará si decide hacer crecer sus sistemas en el futuro.

Sin embargo, aquí hay algunas cosas que debe tener en cuenta (IMO):

  1. El código SQL generado es malo (excepciones a seguir). Lo siento, sé que mucha gente piensa que es un gran ahorro de tiempo, pero nunca he encontrado un sistema que pueda generar un código más eficiente que el que podría escribir y, a menudo, el código es simplemente horrible. También a menudo terminas generando una tonelada de código SQL que nunca se usa. La excepción aquí son los patrones muy simples, como las tablas de búsqueda. Sin embargo, mucha gente se deja llevar por eso.
  2. Entidades <> Tablas (o incluso entidades del modelo de datos lógico necesariamente). Un modelo de datos a menudo tiene reglas de datos que se deben aplicar lo más cerca posible de la base de datos, lo que puede incluir reglas sobre cómo las filas de la tabla se relacionan entre sí u otras reglas similares que son demasiado complejas para RI declarativa. Estos deben manejarse en procedimientos almacenados. Si todos sus procedimientos almacenados son simples procedimientos CRUD, no puede hacerlo. Además de eso, el modelo CRUD generalmente crea problemas de rendimiento porque no minimiza los viajes de ida y vuelta a través de la red a la base de datos. Ese suele ser el mayor cuello de botella en una aplicación empresarial.
Tom H
fuente
Acordado en SQL generado. Siempre causa más problemas de los que resuelve. Y estoy muy en contra de simplemente crear una capa CRUD con procesos almacenados. Los procs deben ser tan gruesos como sea posible. No estoy seguro de cómo definir "una aplicación".
Eric Z Beard
Por una aplicación, me refiero a una sola aplicación escrita por un solo grupo en la organización. Donde estoy consultando ahora tienen una base de datos corporativa a la que acceden al menos tres grupos separados que trabajan en tres aplicaciones diferentes con una comunicación limitada entre ellos.
Tom H
1

A veces, su aplicación y la capa de datos no están tan estrechamente unidas. Por ejemplo, puede tener una aplicación de facturación telefónica. Luego, crea una aplicación separada que monitorea el uso del teléfono para a) publicitarle mejor b) optimizar su plan telefónico.

Estas aplicaciones tienen diferentes preocupaciones y requisitos de datos (incluso los datos provienen de la misma base de datos), impulsarían diferentes diseños. Su base de código puede terminar en un desastre absoluto (en cualquier aplicación) y una pesadilla para mantener si deja que la base de datos controle el código.

billybob
fuente
1

Las aplicaciones que tienen una lógica de dominio separada de la lógica de almacenamiento de datos se pueden adaptar a cualquier tipo de aplicación de origen de datos (base de datos o de otro tipo) o UI (web o Windows (o Linux, etc.)).

Estás prácticamente atascado en tu base de datos, lo que no está mal si estás con una empresa que está satisfecha con el sistema de base de datos actual que estás utilizando. Sin embargo, debido a que las bases de datos evolucionan a lo largo del tiempo, puede haber un nuevo sistema de base de datos que esté realmente limpio y nuevo que su empresa quiera usar. ¿Qué pasaría si quisieran cambiar a un método de servicios web de acceso a datos (como lo hace alguna vez la arquitectura orientada al servicio)? Puede que tenga que portar sus procedimientos almacenados en todo el lugar.

Además, la lógica de dominio abstrae la interfaz de usuario, que puede ser más importante en sistemas complejos grandes que siempre han evolucionado (especialmente cuando están buscando constantemente más clientes).

Además, si bien estoy de acuerdo en que no hay una respuesta definitiva a la pregunta de los procedimientos almacenados versus la lógica de dominio. Estoy en el campo de la lógica de dominio (y creo que están ganando con el tiempo), porque creo que los procedimientos almacenados elaborados son más difíciles de mantener que la lógica de dominio elaborada. Pero ese es otro debate

Mark Rogers
fuente
0

Creo que solo estás acostumbrado a escribir un tipo específico de aplicación y resolver un cierto tipo de problema. Parece que estás atacando esto desde una perspectiva de "base de datos primero". Hay muchos desarrolladores por ahí donde los datos persisten en una base de datos, pero el rendimiento no es una prioridad. En muchos casos, poner una abstracción sobre la capa de persistencia simplifica enormemente el código y el costo de rendimiento no es un problema.

Lo que sea que estés haciendo, no es OOP. No está mal, simplemente no es POO, y no tiene sentido aplicar sus soluciones a todos los problemas que existen.

Programador ilegal
fuente
Los datos siempre son lo primero. Es la razón por la que tienes el programa de computadora en primer lugar. Por lo tanto, "la base de datos primero" es posiblemente el único enfoque válido para diseñar aplicaciones.
gbjbaanb
0

Interesante pregunta. Un par de pensamientos:

  1. ¿Cómo probaría la unidad si toda su lógica de negocios estuviera en su base de datos?
  2. ¿Los cambios en la estructura de su base de datos, específicamente los que afectan a varias páginas en su aplicación, serían una molestia importante para cambiar en toda la aplicación?
Kevin Pang
fuente
0

¡Buena pregunta!

Un enfoque que prefiero es crear un objeto iterador / generador que emita instancias de objetos que sean relevantes para un contexto específico. Por lo general, este objeto envuelve algunas cosas de acceso a la base de datos subyacentes, pero no necesito saberlo cuando lo uso.

Por ejemplo,

Un objeto AnswerIterator genera AnswerIterator. Responde objetos. Bajo el capó está iterando sobre una instrucción SQL para obtener todas las respuestas, y otra instrucción SQL para obtener todos los comentarios relacionados. Pero cuando uso el iterador solo uso el objeto Answer que tiene las propiedades mínimas para este contexto. Con un poco de código esqueleto, esto se vuelve casi trivial.

Descubrí que esto funciona bien cuando tengo un gran conjunto de datos para trabajar, y cuando lo hago bien, me da objetos pequeños y transitorios que son relativamente fáciles de probar.

Básicamente es una fina capa sobre el material de Acceso a la base de datos, pero todavía me da la flexibilidad de abstraerlo cuando lo necesito.

Allain Lalonde
fuente
0

Los objetos en mis aplicaciones tienden a relacionarse uno a uno con la base de datos, pero creo que usar Linq To Sql en lugar de sprocs hace que sea mucho más fácil escribir consultas complicadas, especialmente poder construirlas usando la ejecución diferida. por ejemplo, desde r en Images.User.Ratings donde etc. Esto me ahorra tratar de resolver varias declaraciones de unión en sql, y tener Skip & Take para paginación también simplifica el código en lugar de tener que incrustar el código row_number & 'over'.

peterorum
fuente
Hay un gran peligro en hacer las cosas de esta manera. Las consultas más complejas terminan necesitando ser reescritas por completo por un DBA para que puedan escalar. Ninguna cantidad de ajuste de índice puede hacer lo que a veces puede hacer cambiar una consulta. Este tipo de Linq2Sql es un acoplamiento extremadamente apretado.
Eric Z Beard el
0

¿Por qué detenerse en objetos de entidad? Si no ve el valor con los objetos de entidad en una aplicación de nivel empresarial, simplemente acceda a sus datos en un lenguaje puramente funcional / de procedimiento y conéctelo a una interfaz de usuario. ¿Por qué no simplemente cortar toda la "pelusa" de OO?

Agilista pragmático
fuente
No veo OO como "pelusa". Es solo que durante la última década más o menos, MSFT, Sun, etc. han escrito el 99% de los objetos que necesitaremos. Solo porque escribo muchas clases estáticas en la parte superior del marco, no significa que no esté usando OO.
Eric Z Beard