Entonces, probablemente, como muchos, a menudo me encuentro con dolores de cabeza con problemas de diseño en los que, por ejemplo, hay algún patrón / enfoque de diseño que parece ajustarse intuitivamente al problema y tiene los beneficios deseados. Muy a menudo hay algunas advertencias que dificultan la implementación del patrón / enfoque sin algún tipo de trabajo en torno al cual luego se niega el beneficio del patrón / enfoque. Puedo terminar fácilmente iterando a través de muchos patrones / enfoques porque, como era de esperar, casi todos tienen algunas advertencias muy significativas en situaciones del mundo real en las que simplemente no hay una solución fácil.
Ejemplo:
Te daré un ejemplo hipotético basado libremente en uno real que encontré recientemente. Digamos que quiero usar la composición sobre la herencia porque las jerarquías de herencia han obstaculizado la escalabilidad del código en el pasado. Podría refactorizar el código pero luego encontrar que hay algunos contextos en los que la superclase / clase base simplemente necesita llamar a la funcionalidad en la subclase, a pesar de los intentos de evitarla.
El siguiente mejor enfoque parece ser la implementación de un patrón de medio delegado / observador y medio patrón de composición para que la superclase pueda delegar el comportamiento o para que la subclase pueda observar eventos de superclase. Entonces, la clase es menos escalable y mantenible porque no está claro cómo se debe extender, también es difícil extender los oyentes / delegados existentes. Además, la información no se oculta bien porque uno comienza a necesitar conocer la implementación para ver cómo extender la superclase (a menos que use comentarios muy extensamente).
Entonces, después de esto, podría optar por simplemente usar observadores o delegados por completo para alejarnos de los inconvenientes que conlleva mezclar los enfoques en gran medida. Sin embargo, esto viene con sus propios problemas. Por ejemplo, podría encontrar que termino necesitando observadores o delegados para una cantidad cada vez mayor de comportamientos hasta que termino necesitando observadores / delegados para prácticamente cada comportamiento. Una opción podría ser tener un gran oyente / delegado para todo el comportamiento, pero luego la clase implementadora termina con muchos métodos vacíos, etc.
Entonces podría intentar otro enfoque, pero hay tantos problemas con eso. Luego el siguiente, y el siguiente, etc.
Este proceso iterativo se vuelve muy difícil cuando cada enfoque parece tener tantos problemas como cualquiera de los otros y conduce a una especie de parálisis de decisión de diseño . También es difícil aceptar que el código terminará siendo igualmente problemático independientemente de qué patrón de diseño o enfoque se use. Si termino en esta situación, ¿significa que el problema en sí necesita ser repensado? ¿Qué hacen los demás cuando se encuentran con esta situación?
Editar: Parece que hay una serie de interpretaciones de la pregunta que quiero aclarar:
- He eliminado la OOP de la pregunta por completo porque resulta que en realidad no es específica de la OOP, además es demasiado fácil interpretar mal algunos de los comentarios que hice al pasar sobre la OOP.
- Algunos han afirmado que debería adoptar un enfoque iterativo e intentar diferentes patrones, o que debería descartar un patrón cuando deje de funcionar. Este es el proceso al que me refería en primer lugar. Pensé que esto estaba claro en el ejemplo, pero podría haberlo dejado más claro, así que he editado la pregunta para hacerlo.