tipos patrones patron observer observador ejemplo diseño design-patterns oop anti-patterns

design-patterns - observer - patrones de diseño ui android



Patrones de diseño mal utilizados (15)

¿Existen, en la lista canónica de Gang of Four, patrones de diseño que a menudo se consideran mal utilizados, incomprendidos o sobreutilizados (aparte del muy disputado Singleton)? En otras palabras, ¿hay un patrón de diseño que aconsejaría pensar dos veces antes de usarlo? (¿Y por qué?)


El más grande que veo es el patrón único en el que no se aplican los cuidados y la diligencia suficiente sobre cómo y cuándo se debe invocar el destructor de un singleton.

Para un patrón tan omnipresente apenas hay discusión sobre el proceso adecuado para decidir cuándo debe morir un singleton.

Solo mi 0.02.

aclamaciones,

Robar


El patrón de observador es bastante inútil en C # porque tiene eventos.


El patrón singleton .. estado global a menudo conduce a problemas al probar

Cualquier código que dependa del singleton se vuelve más y más difícil de probar porque esa dependencia no se burla fácilmente.


En realidad, lo que veo más a menudo es la falta de uso de un patrón apropiado. Escenario típico: yo: "Oye, el módulo A ya tiene un fragmento de código que recorre un conjunto de objetos y realiza la operación de la base de datos X en ellos, ¿por qué no reutilizaste ese código?" codificador: "bueno, pero tuve que hacer la operación Y en esos objetos". Yo: "¿Qué pasa con el uso de refactorización para utilizar el patrón de comando para ejecutar X o Y, según corresponda?"

Una vez vi como el uso del patrón Subject-Observer se salía de control. Se implementó entre procesos que usan la base de datos para almacenar persistentemente el Sujeto. Debido a la gran cantidad de actualizaciones sobre el tema y el número de observadores, la carga en la base de datos fue enorme y causó una desaceleración imprevista en todo el sistema.


Patrones de fábrica ...

Me lanzaron en paracaídas en un proyecto antes, donde cada uno de MyObject en el sistema tenía un MyObjectFactory equivalente para generar nuevas instancias. No existía el concepto de abstracción o clases ampliadas ... simplemente viejo ClassX y ClassXFactory.

Y nadie podría explicar por qué ... "Así era como siempre se habían hecho las cosas"


El patrón del Mediador definitivamente tiene el potencial de ser mal usado si todo tipo de lógica se engloba en una gran clase.


Yo también diría el patrón de fábrica. Experiencia similar a Eoin. En mi caso, el proyecto tenía toneladas de fábricas porque algunas personas pensaban que podrías haber usado el objeto A para una implementación local y el objeto B para el remoto y fue abstraído a través de una fábrica (lo cual es algo sensato que hacer).

Pero la implementación "remota" nunca se ha necesitado o implementado o incluso previsto en el futuro ... y también, los ingenieros menos capacitados comenzaron a adoptar el patrón para muchas otras cosas solo como cortador de galletas ...


En realidad, diría que los patrones de diseño en general se usan en exceso cuando se usa KISS ( Mantenlo simple, estúpido Keep it Short and Simple) solución es todo lo que se necesita.

Los patrones de diseño son excelentes para hacer que un sistema sea flexible, pero a costa de hacer la implementación más compleja. Esto es solo una valiosa compensación cuando la flexibilidad proporcionará una ventaja práctica.


Primero, "depende" del idioma: algunas estructuras en algunos idiomas disminuyen la necesidad de ciertos patrones de diseño.

En segundo lugar, parte de la plantilla para el concepto de un Patrón de diseño desde el principio ha incluido secciones para "Aplicabilidad" y "Consecuencias": ignórelas bajo su propio riesgo. "Conocer" un patrón no solo significa que usted sabe cómo codificarlo en el idioma de su elección; también significa saber cuándo usarlo y qué inconvenientes puede tener.


TODAS.

No me malinterpreten aquí, considero que son una gran base y cuando se entienden bien, son muy útiles. Le cuesta tanto adquirir las habilidades de diseño para saber cuándo y cómo aplicarlas en el código. En realidad, ese es el caso general de las habilidades para crear código limpio.

No se trata de no usar entonces, es exactamente lo que dijiste en la pregunta "piensa dos veces antes de usar". Comprenda bien lo que está haciendo y por qué. Si no lo hace, hable con alguien que pueda aconsejarlo sobre eso, además de leer mucho. Tenga cuidado con los que conocen todos los patrones, pero no puede explicarle claramente el qué / por qué de ninguno de ellos, especialmente del que está en cuestión.


Solo quería agregar otro comentario después de ver algunas de las respuestas "Todos los patrones son malos".

Si usted es un programador medio decente que trabaja en problemas moderadamente desafiantes, casi todos los patrones deberían haberse presentado en un punto u otro como la solución "obvia" a un problema.

El único punto real del libro Design Patterns fue poner nombres a lo que todos hacemos todos los días para que podamos comunicarnos mejor.

Supongo que si eres un programador novelesco, sería muy útil leerlos para que el día que los necesites no tengas que resolverlo solo, ya esté en tu caja de herramientas, pero en general, cualquier de estos podría ser resuelto por una Gang of One (anyOne!).

Si hay alguno de estos que aún no conoces, probablemente nunca lo necesites.

Es bastante útil poner nombres a los patrones y formalizarlos un poco, no me quejo del libro en absoluto. Si no ves la necesidad ocasional de casi todos los patrones aquí, simplemente no estás trabajando en un código muy difícil (o duplicas mucho el código, algo que considero el pecado cardinal).


El único (además del mencionado Singleton y su socio en el crimen, la fábrica) no sería un GoF, sería setters y getters cuando se aplica a las propiedades nativas de un objeto.

Setters y getters aplicados a las variables miembro son funcionalmente idénticos a las variables de miembro público. Un getter sin setter se parece más a una variable miembro pública final, pero en ese punto, ¿por qué no usar solo una variable pública miembro final, ya no hacen daño ...?

La única diferencia es que "podría" interceptar la llamada y anularla, pero las personas rara vez lo hacen. Más a menudo se usa como una muleta para los programadores de procedimientos para evitar la programación OO (que es la verdadera razón por la cual es un antipatrón).

Con un setter y / o getter todavía está exponiendo su estructura interna de miembros al mundo exterior (por ejemplo, tendrá que refactorizar otras clases si encuentra que necesita cambiar una int a una larga) y está casi asegurando que algunos códigos que deberían estar dentro de su objeto se colocan afuera.

Hay algunas excepciones que puedo pensar:

Setters solía simplificar la construcción de un objeto. A veces es necesario crear un objeto y luego establecer otros valores después. Estos valores deben ser inmutables (no debe poder llamar al grupo dos veces) por seguridad.

Getters solía acceder a los objetos contenidos. Dado que los objetos contenidos son usualmente capaces de asegurar su propia integridad, compartirlos es genial. En este caso, los incubadores generalmente son malos. No desea que un objeto con un estado específico intercambiado salga justo debajo de su nariz, hace que sea mucho más difícil asegurar su propia integridad.

Java Beans utilizado para los componentes de la pantalla: Sí, no se puede encontrar una mejor manera de implementar estas "bolas de propiedad". La reflexión es útil para este componente, los patrones son útiles; es un tanto hacky pero funciona.

Objetos DAO / DTO Bean. Honestamente, creo que estos son un uso dudoso del patrón, pero son el patrón. Hace que la manipulación de las propiedades a través de los metadatos en lugar del código sea mucho más difícil de lo que debería ser, ya que tiene que ser reflectante. Las propiedades de los beans siempre están ligadas a alguna fuente externa (formato de base de datos, formato de transferencia de datos, propiedades de los componentes, ...) entonces, ¿por qué estamos duplicando el trabajo de definición de cada parte?

Editar: robado del comentario de kyoryu, apareció en la publicación porque es realmente un resumen perfecto de lo que estaba diciendo y podría perderse en los comentarios. Necesario ya que no todo el mundo parece tener el concepto de que agregar accesores al lenguaje solo codifica un patrón de diseño de OO incorrecto:

Version corta -

if (account1.balance > 1000) { account1.balance = account1.balance - 1000; account2.balance = account2.balance + 1000; }; = BAD CODE. account2.deposit(account1.withdraw(1000)); = GOOD CODE.

El segundo no requiere accesadores ... - kyoryu (Ligeramente modificado por bill k porque tengo un poco más de espacio que en su comentario).

El segundo mueve la prueba y algunas otras operaciones matemáticas dentro de la Cuenta en lugar de duplicarla en el código en cada lugar donde realice una transferencia.

Para aclarar el punto MÁS, tenga en cuenta que con el estilo "BUEN CÓDIGO" es bastante obvio que el resultado de .withdraw podría ser un objeto Transacción que contenga información sobre la transacción completa, incluido su éxito, origen y destino y la capacidad de registro. ¿Cómo se le habría ocurrido esto a alguien que escribe su código en el estilo "BAD CODE"?

Además, ¿cómo se podría refactorizar BAD CODE incluso para usar un objeto así? Es solo un desastre.


Solo usa un patrón cuando sea necesario. No se puede predecir el futuro, de modo que si bien se puede poner un patrón para hacer el diseño flexible, ¿qué sucede cuando el producto toma una dirección diferente y su patrón se convierte en lo que le impide implementar lo que sus usuarios quieren?

Mantenga los diseños lo más simple posible para comenzar. Cuando sepa más acerca de cómo debe cambiar su diseño, use el patrón apropiado y no antes.


PATRÓN DE REPOSITORIO

La mayoría de las personas comienzan a usar este patrón justo después de leer el libro de Diseño impulsado por el dominio de Eric Evans.

¿Cuántas personas aquí han visto repositorios construidos como objetos de acceso a datos?


No puedes tener una respuesta directa para esta pregunta. Es principalmente subjetivo y depende de los requisitos de la aplicación.

  1. La mayoría de las personas indicaron que Singleton_pattern es malo, pero no es malo para todos los usuarios y proyectos. Para los requisitos de mi proyecto, sirve para el propósito. Necesito un ConnectionManager para gestionar la sesión entre el Cliente y la Aplicación y Singleton hace el trabajo de forma brillante.

  2. Le ha dado un frasco de terceros con buena documentación. El contenedor contiene una jerarquía de herencia. Ahora tiene que agregar una operación en cada niño. Como no tienes el código fuente, no puedes hacerlo. Ahora puedes beneficiarte usando Visitor_pattern . Pero si tiene un código fuente, no puede usar ningún patrón de Visitor . Puede agregar una operación nueva simple en el padre y cada hijo. La falta de código fuente no implica que esté haciendo un mal uso del patrón de Visitor .

  3. Quiero limitar la comunicación entre varios objetos. Voy a continuar con implementar Mediator_pattern para la comunicación de objetos. Quiero limitar la exposición del cliente a mi sistema para ocultar la complejidad. Voy a seguir adelante con Facade_pattern . Eso no quiere decir que estoy usando mal estos patrones. Este mismo ejemplo se puede extender a otros patrones como Proxy_pattern, etc.