Recientemente, estaba discutiendo con otro programador la mejor manera de refactorizar un método enorme (1000 líneas) lleno de declaraciones "if".¿Cuáles son las ventajas de la cadena de responsabilidad frente a las listas de clases?
El código está escrito en Java, pero creo que este problema podría ocurrir en otros lenguajes, como C# también.
Para resolver este problema, sugirió usar un patrón de cadena de responsabilidad. Propuso tener una clase básica de "Manejador". Entonces, "Handler1", "Handler2", etc. extenderían "Handler".
Entonces, los manejadores tendrían un método "getSuccessor", que devolvería null (si era el último de la cadena) o el siguiente controlador de la cadena.
Luego, una función "handleRequest (Request)" trataría con Request o la pasaría al siguiente de la cadena y, si ninguna de las soluciones previas funcionó, devolvería simplemente null o arrojaría una excepción.
Para agregar un nuevo controlador a la cadena, el codificador iría al último elemento de la cadena y le indicaría que había un elemento nuevo. Para hacer algo, simplemente llama a handleRequest en el primer elemento de la cadena.
Para resolver este problema, sugerí usar un enfoque diferente.
Tendría una clase base "Handler" también, con "Handler1", "Handler2", al igual que el método anterior mencionado.
Sin embargo, no habría ningún método "getSuccessor". En cambio, tendría una clase Collection con una lista de controladores (un Vector, una ArrayList, o lo que sea mejor en este caso).
La función handleRequest todavía existiría, pero no propagaría la llamada a los siguientes controladores. Solo procesaría la solicitud o devolvería null.
para manejar una petición, se podría usar
for(Handler handle : handlers){
result = handle.handleRequest(request);
if(result!=null) return result;
}
throw new CouldNotParseRequestException(); //just like in the other approach
O, para evitar la duplicación de código, un "parseRequest (petición)" método podría ser añadido a la clase de colección. Para agregar un nuevo controlador, uno iría al constructor de la colección (o al bloque static {}, o algo similar) y simplemente agregaría el código "addHandler (new Handler3());".
Exactamente qué ventajas de la cadena de responsabilidad me estoy perdiendo con este enfoque? ¿Qué método es mejor (suponiendo que es el mejor método)? ¿Por qué? ¿Qué posibles errores y problemas puede causar cada método de diseño?
Para aquellos que necesitan contexto, aquí es lo que el código original parecía:
if(x instanceof Type1)
{
//doSomething1
} else if(x instanceof Type2)
{
//doSomething2
}
//etc.
recursividad muy profunda no debería ser un problema. Es relativamente pequeño (en ninguna parte cerca de las miles de llamadas a métodos necesarias para apilar el sistema de desbordamiento). – luiscubal