2009-12-28 17 views
7

He usado Rails durante más de 4 años, así que obviamente me gusta Rails y me gusta hacer cosas como Rails Way y, a veces, sin saberlo, me paso al lado oscuro.¿Usamos Rails ActiveRecord como estructura híbrida, es decir, estructura de datos + objeto?

Recientemente recogí Clean Code por Uncle Bob. Estoy en el Capítulo 6 y estoy un poco confundido acerca de si los desarrolladores de los raíles rompemos la regla fundamental del diseño OO, es decir, la Ley de Demeter o la encapsulación. La Ley de Demeter establece que un objeto no debe conocer las entrañas de otro objeto y no debe invocar métodos sobre objetos que son devueltos por un método, porque cuando haces eso sugiere que un objeto sabe demasiado sobre el otro objeto.

Pero muy a menudo llamamos métodos a otro objeto desde un modelo. Por ejemplo, cuando tenemos una relación como 'Un pedido pertenece a un usuario'. Entonces muy a menudo terminamos haciendo order.user.name o para evitar que parezca un accidente de tren, configuramos un delegado para hacer order.name.

  1. No es que todavía como romper la Ley de Demeter o encapsulación?

  2. La otra pregunta es: ¿ActiveRecord es solo una estructura de datos o un objeto de transferencia de datos que interactúa con la base de datos?

  3. En caso afirmativo, ¿no creamos una estructura híbrida, es decir, medio objeto y mitad de estructura de datos al poner nuestras reglas comerciales en los modelos ActiveRecord?

+1

Nunca tome los libros demasiado en serio. Excepto "Código Completo" por supuesto. – vava

+1

Tales "reglas" y "leyes" son solo sugerencias para hacer que el código esté limpio. Cuando es más limpio violarlos, solo hazlo. – luikore

+0

Definitivamente puedo violar una regla intencionalmente si sé que esta violación no va a causar un problema de diseño a largo plazo y, sobre todo, si hay una manera de lograr un código más limpio sin violar ninguna regla, esa será la ruta preferible:) – nas

Respuesta

15

Rails is Rails. Qué más hay que decir. Sí, algunos de los modismos en Rails violan buenos principios de diseño. Pero toleramos esto porque es el camino de Rails.

Habiendo dicho eso, hay demasiado uso del modelo en la mayoría de las aplicaciones de rieles. Con demasiada frecuencia veo que el código de vista accede directamente a los modelos. Veo reglas comerciales dobladas en el objeto de registro activo. Un mejor enfoque sería aislar las reglas comerciales de los registros activos y aislar las vistas de los modelos. Esto no violaría ningún modismo de rieles, y haría que las aplicaciones de rieles fueran mucho más flexibles y mantenibles.

+1

¿Realmente valdría la pena introducir aún más objetos en un sistema de 2000 líneas? ¿Estoy de acuerdo con un sistema de 10k +, pero a menor escala? –

+0

Si eso hace que el diseño sea más limpio y más fácil de ampliar, entonces creo que se debe tener en cuenta porque he visto aplicaciones de rieles con más de 200 modelos y algunos modelos tienen más de 1000 líneas. Ahora uno puede decir que es porque el diseño es malo. Podría haber muchas razones para eso, pero una de ellas podría no estar siguiendo o violando principios básicos. Eso es solo un pensamiento. – nas

+0

En mi humilde opinión, lo que tío bob dijo anteriormente "Un mejor enfoque sería aislar las reglas comerciales de los registros activos y aislar las vistas de los modelos". tiene sentido. La pregunta es: ¿cómo se puede hacer limpiamente si hay un objeto ActiveRecord de orden o de usuario y es necesario que haya un conjunto de reglas comerciales para ellos? – nas

7

mi humilde opinión, si se sigue el enfoque purista demasiado, entonces se termina en un desastre como Java, donde se utiliza todos los patrones de diseño correctas pero nadie puede recordar las ocho líneas de código que necesita sólo para abrir una archive y lea sus contenidos.

El marco ActiveRecord de Rails es una implementación de Martin Fowler's Active Record design pattern. Active Records in Rails ciertamente no son solo estructuras de datos estúpidas o DTO porque tienen un comportamiento: realizan la validación, pueden decirle si sus atributos han cambiado, etc. y usted es libre y de hecho encouraged, para agregar su propia lógica de negocios allí .

Rails en general fomenta las buenas prácticas, p. MVC y vinagre sintáctico para hacer las cosas malas difíciles y/o feas.

+0

Rails definitivamente alienta las buenas prácticas, y como mencionas una de las premisas básicas es MVC, controlador delgado y modelo de grasa, etc. Sin embargo, sobre tu primera parte de la respuesta no estoy seguro si alguien realmente puede terminar en un lío siguiendo los patrones correctos en cualquier idioma en particular, aunque definitivamente se puede crear un desastre en cualquier idioma, incluido el rubí, mediante la aplicación ciega de un patrón de diseño que no es adecuado para un problema determinado. – nas

+0

En el caso de Java, es un desastre porque dificulta la productividad. Es extremadamente fácil hacer las cosas con Rails. –

+0

¡Es cierto y no podría estar más de acuerdo! Pero si tiene una pequeña aplicación de rieles y si no sigue los buenos principios de diseño, entonces puede no importar mucho. Aunque cuando la aplicación crece por encima de cierto nivel y sigues añadiendo código sin pensar mucho, puede volverse tan desordenado como cualquier otro código escrito en cualquier otro idioma. Especialmente cuando ve restos de trenes (order.user.name.split ('')) y objetos de Modelo a los que se accede directamente desde las vistas. Se convierte en una pesadilla mantener y agregar nuevas características al código existente. – nas

1

En relación con "Law of Demeter", una cosa que no he mencionado es el concepto de distancia. Con eso quiero decir, "¿Cuán estrechamente relacionado está el objeto involucrado?" En mi opinión, esto supondría una cierta diferencia si me interesa seguir "La ley de Demeter" o no.

En el caso de ActiveRecord, los objetos implicados en la mayoría de las infracciones de LoD están inseparablemente unidos en una estrecha relación. Cambiar la estructura de datos interna de estos objetos requiere un cambio en la base de datos para reflejar esa nueva estructura.Las tablas de una base de datos suelen estar "unidas" en una única base de datos, que incluso refleja estas "asociaciones" a través de restricciones de clave externa (o al menos contiene claves externas &).

Así que, en general, no me preocupo por seguir LoD entre mis objetos AR. Sé que están estrechamente unidos debido a su propia naturaleza.

Por otro lado, me preocuparía más LoD entre objetos más distantes, especialmente aquellos que cruzan límites de MVC o cualquier otro dispositivo de diseño.

4

Sí, ActiveRecord rompe deliberadamente la encapsulación. Esto no es tanto una limitación de Rails, ya que es una limitación del patrón en el que se basa. Martin Fowler, cuya definición de ActiveRecord era más o menos de los rieles plantilla utilizada, dice tanto en el capítulo ActiveRecord de POEAA:

Otro argumento en contra activo Registro es el hecho de que las parejas el diseño de objetos de la base de datos diseño. Esto hace que sea más difícil refactorizar el diseño como un proyecto en adelante.

Este es un common criticism de rieles de otros marcos. Fowler dice a sí mismo ActiveRecord es principalmente para ser utilizado

... para la lógica de dominio que no es demasiado compleja ... si su lógica de negocio es compleja, pronto desea utilizar su directa del objeto relaciones, colecciones, herencia, etc. Estos no se asignan fácilmente en Active Record.

Fowler continúa diciendo que, para aplicaciones más graves con la lógica de dominio complejo del Data Mapper pattern, lo que hace un mejor trabajo de separar las capas, es preferible. Esta es una de las razones por las que Rails upcoming move to Merb se ha visto generalmente como un movimiento positivo para Rails, ya que Merb utiliza el patrón DataMapper además de ActiveRecord.

No estoy seguro Demeter es la principal preocupación con ActiveRecord. Más bien, creo que romper la encapsulación entre los datos y las capas de dominio rompe el Single Responsibility Principle de Uncle Bob. Demeter creo que es más un ejemplo específico de cómo seguir el Principio Abierto/Cerrado. Pero creo que la idea más amplia detrás de todo esto es la misma: las clases deberían hacer una cosa y ser robustos frente a los cambios futuros, que hasta cierto punto no es ActiveRecord.

Cuestiones relacionadas