¿Diferencia entre los patrones de diseño de Fachada, Proxy, Adaptador y Decorador? [cerrado]

135

¿Cuál es la diferencia entre los patrones de diseño de Fachada, Proxy, Adaptador y Decorador?

Nunca he leído una explicación clara, ¿cuál es la tuya?

usuario310291
fuente
@gavenkoa la otra pregunta es solo sobre proxy y decorador
user310291
2
Increíble como alguna pregunta cerrada se revela tan útil.
Lucas

Respuestas:

286

El adaptador adapta una clase / objeto dado a una nueva interfaz. En el caso de la primera, típicamente se emplea la herencia múltiple. En el último caso, el objeto está envuelto por un objeto adaptador conforme y se pasa. El problema que estamos resolviendo aquí es el de las interfaces no compatibles .

Fachada es más como una simple puerta de entrada a un conjunto complicado de funcionalidades. Usted crea una caja negra para que sus clientes se preocupen menos, es decir, simplifiquen las interfaces .

Proxy proporciona la misma interfaz que la clase proxied-for y, por lo general, realiza algunas tareas de limpieza por su cuenta. (Entonces, en lugar de hacer múltiples copias de un objeto pesado, Xusted hace copias de un proxy ligero Pque a su vez administra Xy traduce sus llamadas según sea necesario). Está resolviendo el problema del cliente de tener que administrar un objeto pesado y / o complejo .

Decorator se utiliza para agregar más pólvora a sus objetos (tenga en cuenta el término objetos: normalmente decora objetos dinámicamente en tiempo de ejecución). No oculta / daña las interfaces existentes del objeto, sino que simplemente lo extiende en tiempo de ejecución .

Ahora que tiene un decorador involucrado, probablemente querrá saber por qué el énfasis en la palabra objeto: algunos lenguajes (como Java) simplemente no permiten la herencia virtual (es decir, la herencia múltiple como lo hace C ++) para permitirle lograr esto en tiempo de compilación.

Dado que hemos arrastrado múltiples herencias (y el temido diamante), buscará mixins , que se ordenan en cadena lineal de interfaces para evitar los problemas de herencia múltiple. Sin embargo, los mixins no se mezclan tan bien. Y terminamos con rasgos , sí, esos pequeños blobs de comportamiento sin estado que ves aparecer todo el tiempo en los parámetros de plantilla en C ++. Los rasgos intentan abordar los problemas de composición y descomposición de la conducta de una manera elegante sin recurrir a herencias múltiples ni al encadenamiento ordenado.

Dirkgently
fuente
1
HTH! He tratado de poner todo lo que puedo sin ser demasiado vago. Disculpe mi incapacidad para hacerlo mejor. He leído (tesis doctoral) documentos sobre rasgos solo. Por lo tanto, mi conocimiento es bastante limitado y no soy lo suficientemente bueno para encajar en todos los patrones en este espacio;)
Dirkgently
¡Anticipaste una futura pregunta sobre mixins y rasgos pero aún no los he visto!
user310291
1
Un buen enlace de comparación (a través de wikipedia) para los primeros tres (el Decorador es bastante diferente): NetObjectives
Liviu
@Liviu Tu enlace está muerto. Supongo que originalmente apuntabas allí , pero el contenido ahora parece estar detrás de un inicio de sesión.
Jonathan H
@Sheljohn Enlace actualizado: p: Un buen enlace de comparación (a través de wikipedia) para los primeros tres (el Decorador es bastante diferente) NetObjectives (Texto de recuperación, ver "entre": "Una de las preguntas más frecuentes que recibo en clase es" ¿Qué es? la diferencia entre Adaptador, Proxy y Fachada? Realmente me parecen lo mismo ".)
Liviu
16

Fachada

Podría usar una fachada, por ejemplo, para hacer que las llamadas a una API sean más fáciles. Eche un vistazo a este ejemplo de fachada remota. La idea aquí es que la implementación completa del código en el servidor está oculta al cliente. El cliente llama a 1 método API que, a su vez, puede realizar 1 o más llamadas API en el servidor.

Adaptador

Un buen ejemplo de esto se puede encontrar aquí , en Wikipedia. Un objeto de cliente Sourcedesea llamar a un método en otro objeto Target, pero la interfaz de ese otro objeto difiere de lo que el cliente espera.

Ingrese el objeto adaptador.

Puede recibir una llamada del Sourceobjeto y, detrás de escena, llamar al Targetmétodo que debe usarse.

Source->CallMethodAOnTarget() ---< Adaptor.CallMethodAOnTarget() this calls ---> Target.MethodWithDifferentSignatureAndName(int i)

En cuanto a Proxy, no tengo ninguna experiencia con este patrón de diseño.

Jason Evans
fuente