[pyar] [Discusión] Django y Single Responsability Pattern

fisa fisadev en gmail.com
Mar Jul 29 12:04:44 ART 2014


Buenas! Ex .net acá. Respondo en items, porque tengo varias ideas de cosas
que quiero responderte:

1) El patrón o guideline de single responsabilitty es un consejo, y muy
borroso. Qué es "1 responsabilidad" depende bastante del contexto y la
persona.
- Alguno te va a decir "se encarga solo de clientes, es 1 responsabilidad"
- Otro mira lo mismo y dice: "eso son 2 responsabilidades, es lógica de
negocio por un lado y persistencia por otro"
- Y un tercero te dice: "eso son N responsabilidades: persistencia, cálculo
de saldo, cálculo de stock, ..."
Y como eso, este tipo de decisiones de "dónde va tal cosa?", "esto es fácil
de mantener?", "queda bien?", etc, son super subjetivas. Lo que voy a poner
yo acá, son mis opiniones después de 12 años de trabajo como desarrollador,
en cosas desde chicas hasta bastante grandes.

2) Muchas veces algunas cosas intermedias que se usan en lenguajes de
tipado estático más estricto, en lenguajes más dinámicos no son necesarias,
complican sin dar nada como ventaja.
Ej: las clases de datos que pasan entre capas en .net, en lugar de pasar
las clases de tu capa de persistencia. En python, si antes tu cliente era
una instancia de un modelo de django, pero ahora pasa a ser otra cosa con
la misma estructura, tu código va a seguir andando, no tenés que actualizar
todos los lugares donde se use. Y por eso es al pedo tener clases
intermedias de datos aparte de las clases de persistencia, para ir pasando
datos entre tus capas, si total podés cambiarlo sin tener que tocar nada de
esas capas. Es un paso extra, mucho más código que mantener, y no te da
ventaja.

Y qué pasa si cambia la estructura de lo que persisto? Ej: agrego 5 campos
nuevos.
Bueno, en ese caso vas a tener que tocar hacia arriba las otras capas,
tengas o no tengas esa separación, porque la estructura de esas clases
intermedias también tendría que actualizarse. En python y sin esas clases,
vas a tener que actualizar bastante menos código, si tenés esas clases
intermedias es bastante más que mantener. Así que sigue sin tener sentido
agregar esas clases para hacerlo "más modificable/mantenible", si implican
más laburo de mantenimiento.

3) Dónde meter cosas como el cálculo de stock, de saldo, etc?

3.a) Hay cosas que son claramente asociables a instancias de algún tipo.
Ej: "calcular el saldo de un cliente", la frase lo dice, es "de un
cliente", así que a mi particularmente me suena re natural que eso sea un
método de Cliente y se use con mi_cliente.calcular_saldo()
Y si mañana ya no uso los modelos de django? no es problema tener la lógica
de negocio ahí? La voy a tener que mover!
No! Si mañana ya no usas django, hacés que esa clase herede de otra cosa en
lugar de Model, y le tocás la definición de los campos para lo que uses
ahora. Si lo hubieses tenido separado en clases distintas, ese laburo de
tocar el modelo lo tenías que hacer igual para crear tu nuevo "persistor".
Así que otra vez, separarlo no te lo hace más fácil de mantener, y no le
veo ninguna ventaja, solo te complicaría el código por todos lados (ej:
siempre además de la instancia de cliente necesitarías instanciar esa otra
cosa de negocio).

3.b) Por otra parte, hay cosas que claramente no son asociables a un
modelo. Ej: "dame el timeline de posts, artículos, mensajes, y fotos". Algo
que va a tener que consultar datos desde muchos lados, mezclarlos,
aplicarles alguna lógica arriba, etc.
Estas cosas en .net se meten en las clases de servicio.
En python+django, como ya dijimos no los meteríamos en un modelo porque no
se asocian claramente a alguno, pero tampoco queremos meter ese código en
la vista (se hace intesteable, poco reutilizable, etc). La solución es
tener algo que provea una api para quienes quieran consumir esta lógica.
Puede ser una clase, o puede ser simplemente un módulo con funciones,
depende del caso.

Y a eso viene algo pegado: "un módulo con funciones sueltas?? eso es feo!"
--un desarrollador java.
Una clase es un molde para crear instancias con estructura y comportamiento
similar. Que java y .net obliguen a que toda lógica sea parte de una clase,
no quiere decir que eso sea bueno. Es una abstracción con un objetivo
definido, y en .net y java te obligan a usar esa abstracción para todo, sin
importar si tenías o no ese objetivo (crear instancias parecidas). Y eso
está mal.

Una función con lógica no necesariamente tiene que estar asociada a una
clase. La función obtener_timeline, no es un comportamiento de una
instancia de nada. Es lógica que yo quiero usar en distintas partes, y
tiene todo el sentido del mundo tener un módulo con esa función y otras
relacionadas adentro, y quien quiera usarlas que las importe y las llame
directamente. Obligar siempre a crear una instancia de algo solamente para
poder llamar a la función, es overhead innecesario, usar una abstracción
que no tiene sentido para ese caso.

Cuándo lo convertiría en una clase? cuando por ejemplo tenga 5 funciones,
que todas reciben una serie de N parámetros iguales. Ej: todas reciben
"conexion, usuario_actual, sesion". En ese caso crearía una clase que tenga
esas cosas como atributos, y las funciones como métodos, para no tener que
pasar siempre esos parámetros a mano.

Pero como todo, es super subjetivo. un buen lispero te va decir que ni
siquiera para eso uses clases :)

Saludos!






El 28 de julio de 2014, 16:52, Jose Selesan <jselesan en gmail.com> escribió:

> Buenas gente!. Estoy leyendo sobre Django (empecé por Django, si no me
> gusta veré Flask o algún otro web framework) y una de las primeras cosas
> que me llamó la atención es que los modelos son más bien modelos de datos,
> ya que especifican los campos y heredan el comportamiento para almacenar en
> la base de datos.
>
> Ahora bien, en los ejemplos que vi, desde la vista misma (ya sea una Class
> View o una función) se persisten las entidades. Esto está bien en ejemplos
> sencillos, pero en casos más complejos, ¿no viola el principio de
> responsabilidad única? Por ejemplo cuando creo una factura, debo hacer las
> validaciones de negocios (que el cliente tenga saldo, que haya stock
> suficiente, etc), actualizar el stock de los productos, actualizar el saldo
> del cliente y persistir la factura con sus items. ¿Donde ponen ese código?
> ¿En la vista? ¿O se crea una clase de de servicio como suele usarse en Java
> o .Net?
>
> José
>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
>



-- 
fisa  -  Juan Pedro Fisanotti
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20140729/0f538048/attachment.html>


More information about the pyar mailing list