OOP: buen diseño de clase

Mi pregunta está relacionada con esta: herramienta de Python que crea un diagtwig de dependencia para los métodos de una clase .

Después de no encontrar ninguna herramienta, escribí un truco rápido: he usado el módulo del comstackdor, he analizado el código fuente en un árbol de origen abstracto y lo he recorrido para recostackr dependencias entre los métodos de clase. Mi script generó un archivo de entrada para graphviz, que se usó para generar un gráfico de dependencia que se parece a esto .

En este punto me he quedado atascado. Me he dado cuenta de que no tengo idea de cómo refactorizar a la clase para que sea menos complicado. Simplemente no sé a qué debo dirigirme. Por ejemplo, en teoría de las bases de datos relacionales hay un par de reglas simples que se utilizan para llevar una base de datos a una forma normal. ¿Qué pasa con alguna teoría similar sobre el diseño de la buena clase (en términos de dependencias entre sus métodos)? ¿Este tema está cubierto en algún lugar para que pueda estudiarlo?

Seguimos los siguientes principios al diseñar las clases:

  • El principio de responsabilidad única : una clase (o método) debe tener una sola razón para cambiar.
  • El principio de cerrado abierto : Una clase (o método) debe estar abierto para extensión y cerrado para modificación.
  • El principio de sustitución de Liskov : los subtipos deben ser sustituibles por sus tipos de base.
  • El principio de segregación de la interfaz : los clientes no deben ser obligados a depender de métodos que no utilizan. Las interfaces deben pertenecer a los clientes.
  • Principio de inversión de dependencia : las abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.

Edición: los patrones de diseño son útiles para que su código cumpla con estos principios. Me ha resultado muy útil entender los principios primero y luego observar los patrones y entender cómo los patrones hacen que su código esté en línea con los principios.

A menudo no es posible decir cuál es ‘correcto’ o ‘incorrecto’ cuando se trata del diseño de clase. Hay muchas pautas, patrones, recomendaciones, etc. sobre este tema, pero al final del día, imho, es mucho sobre la experiencia con proyectos anteriores. Mi experiencia es que es mejor no preocuparse demasiado por eso y mejorar gradualmente su código / estructura en pequeños pasos. Experimente y vea cómo se sienten / parecen algunas ideas / cambios. Y, por supuesto, siempre es una buena idea aprender de los demás. lee mucho código y analízalo, trata de entender :).

Si desea leer sobre la teoría, puedo recomendar la aplicación de UML y patrones de Craig Larmanns: una introducción al análisis y diseño orientado a objetos y el desarrollo iterativo de Amazon . Cubre varias partes de su pregunta, da algunas pautas aproximadas y las muestra usando una aplicación de ejemplo. Me gustó el libro.

¿Podrías subir tu aplicación en algún lugar? Tal vez en Github o algo así, quizás puedas pedir algunos consejos concretos.

Los patrones de diseño se han convertido en el estándar de facto para un diseño de buena clase. En general, cada patrón tiene un caso de uso particular, o escenario, al que se aplica. Si puede identificar esto en su código, puede usar el patrón para crear algo que tenga más sentido y, por lo general, tenga menos dependencias.

La refactorización es la herramienta que usaría para lograr estos cambios radicales. Un buen IDE te ayudará a refactorizar.

Intenta hacer cada método fácilmente comprobable por unidad. Me parece que esto siempre conduce a mis diseños hacia una mayor legibilidad / comprensión. Existen numerosas reglas OOAD: SRP, DRY, etc. Trate de tenerlas en cuenta al refactorizar.

Recomiendo el libro “Refactoring” de Martin Fowler para ver muchos ejemplos prácticos de cómo convertir de manera iterativa un diseño deficiente en un buen diseño.