2009-03-13 10 views
13

Me he topado con un patrón de diseño que se conoce como "Patrón de controlador", pero no puedo encontrar ninguna referencia real a este patrón en ninguna parte. Básicamente es solo una interfaz de un solo método que le permite ampliar fácilmente la funcionalidad en el back-end sin hacer que los clientes vuelvan a compilar. Podría ser útil para un servicio web que tiene que manejar muchos tipos diferentes de solicitudes. He aquí un ejemplo:patrón de "controlador"?

public interface IHandler 
{ 
    IDictionary<string, string> Handle(IDictionary<string, string> args); 
} 

Los argumentos incluirían típicamente una clave como "acción" con un valor que indica al implmentation qué hacer. Se pueden pasar args adicionales para dar a la impl más información. El impl luego devuelve una lista arbitraria de argumentos que el cliente "debería" entender.

¿Es este un patrón anti, o tal vez otro patrón disfrazado? ¿Se recomienda este tipo de diseño?

EDIT: Un poco más de información: La forma en que he visto esto implementado, el controlador "raíz" actuaría como un despachador a otros controladores concretos (¿tal vez?). El controlador de raíz tiene un "HandlerResolver", que decide qué manejador concreto debe obtener el mensaje en función de su contenido. Tal vez es realmente como un patrón de "despachador", aunque no sé si eso es realmente un patrón. Supongo que también podría tener un patrón de cadena de responsabilidad en la raíz, que le permite encadenar a un grupo de manipuladores de concreto, y luego dejarlos decidir cuál manejará.

Respuesta

9

Es la forma en programación orientada a objetos para hacer cierres en idiomas que no las tienen. no tenía un nombre de "patrón" porque en los lenguajes funcionales es la forma obvia de trabajar. en los lenguajes de OOP, OTOH, tienes que hacer un poco de trabajo, por lo que parece una expresión idiomática. 'Handler' suena bien.

(que no es un producto único, por cierto)

1

No sé si es realmente recomendable, pero en realidad he tenido que usar ese tipo de patrón en algunas aplicaciones MATLAB que he escrito para imitar el comportamiento de referencia de los objetos (que ahora no es necesario con las versiones más recientes))

Irónicamente, en realidad llamé a la función "manejador". Mi objeto simplemente almacenaba un campo que contenía una referencia de manejador de función (@handler) y los métodos eran solo contenedores que llamaban a esta función. Por ejemplo, una función que se sobrecargan para el objeto acaba de llamar:

object.handler('get',...input argument list...) 

No estoy seguro de si esto se considera una "buena" opción de diseño en otros idiomas. Lo elegí por necesidad, porque era la única forma en que me cruzaba para crear un comportamiento de referencia en MATLAB (la función del manejador tenía acceso a un espacio de trabajo de datos inicializados que no tenía que pasar dentro y fuera de los diversos llamadas a métodos). Las versiones más nuevas de MATLAB ahora tienen una clase HANDLE que puede hacer esto de una manera mucho más limpia.

2

lo uso bajo el nombre de "SingletonRegistry"

Ver this thread

he usarlo un par de veces. Especialmente cuando las acciones a realizar se desconocen por adelantado (en las primeras fases del diseño) o la aplicación debe admitir una flexibilidad extrema.

Cargo el diccionario desde un archivo o una base de datos, y creo una sola instancia de la clase que manejará la solicitud bajo cierta "clave".

He encontrado class also buscando en la web ese nombre.

Parece que no es lo mismo?

2

Como tiene la palabra "Acción" en su publicación, me hacen creer que esto podría ser parte del patrón de comando. Eche un vistazo a la Wiki y busque "Handler" ... quizás esto le dará un poco más de información.

http://en.wikipedia.org/wiki/Command_pattern

+0

Sí, el patrón de comando fue mi primera suposición para qué era esto. Creo que Command utiliza algo similar a esto internamente con el método "Execute". –

1

Creo que el objetivo de evitar recompilaciones está mucho mejor servida por un diseño influenciado COM . Lo flexibilidad Qué se obtiene de esto:

IHandler UserHandler = ...; 

Dictionary<string,string> result = UserHandler.Handle(
    new Dictionary<string, string>{ 
     { "Action", "AddUser" }, 
     { "UserName", "Joe Bloggs" }, 
     { "Age", "23" } }); 
NewUserId = Int.Parse(result["UserId"]); 

sobre: ​​

IUserHandler UserHandler = ...; 

AddUserResult result = UserHandler.AddUser(new AddUserArgs { 
    UserName = "Joe Bloggs", 
    Age = 23 }); 
NewUserId = result.UserId; 

cuando se puede extender las acciones, los resultados y argumentos:

IUserHandler UserHandler = ...; 

AddUserResult2 result = UserHandler.AddUser(new AddUserArgs2 { 
    UserName = "Joe Bloggs", 
    Age = 23, 
    Password = "xyzzy" }); 
NewUserId = result.UserId; 
SessionId = result.SessionId; 

IUserHandler2 UserHandler2 = UserHandler as IUserHandler2; 
if (UserHandler2 != null) 
{ 
    LoginUserResult loginResult = UserHandler2.LoginUser(new LoginUserArgs { 
     UserId = NewUserId, 
     SessionId = SessionId, 
     Password = "xyzzy" }); 
} 
+0

Supongo que la única flexibilidad adicional que se obtiene con "Manejar" es que ni siquiera necesita un método específico en la interfaz como "AddUser" o "LoginUser". Con handle, obtiene una flexibilidad infinita en lo que puede hacer la interfaz, a costa de la usabilidad. –

+0

Es por eso que tuve el ejemplo IUserHandler2, que muestra que también puede agregar nuevas acciones. Es un poco más detallado en general, pero prefiero la capacidad de descubrimiento, y la clara retroalimentación sobre qué versión está disponible. Además, puede verificar la disponibilidad del método cuando se conecta. –

+0

Acepto, el método "manejar" definitivamente apesta por descubrimebilidad –

0

he visto el " Handler "imparte clases en bases de códigos heredados, especialmente para servicios web. Por lo que he visto, estos suelen ser un Adaptador, Fachada o algún patrón similar y terminan llamándose Manipulador porque maneja una solicitud.

Cuestiones relacionadas