Por un lado, grandes grupos de if/else
bloques no son fácilmente comprobables . Cada nueva "rama" agrega otra ruta de ejecución y, por lo tanto, aumenta la complejidad ciclomática . Si desea probar su código a fondo, tendría que cubrir todas las rutas de ejecución, y cada condición requeriría que escriba al menos una prueba más (suponiendo que escriba pruebas pequeñas y enfocadas). Por otro lado, las clases que implementan estrategias suelen exponer solo 1 método público, que es fácil de probar.
Entonces, con anidado if/else
, terminará con muchas pruebas para una sola parte de su código, mientras que con Estrategia tendrá pocas pruebas para cada una de las estrategias más simples. Con este último, es fácil tener una mejor cobertura, porque es más difícil pasar por alto las rutas de ejecución.
En cuanto a la extensibilidad , imagine que está escribiendo un marco, donde se supone que los usuarios pueden inyectar su propio comportamiento. Por ejemplo, desea crear algún tipo de marco de cálculo de impuestos y desea apoyar los sistemas fiscales de diferentes países. En lugar de implementarlos todos, solo desea dar a los usuarios del marco la oportunidad de proporcionar una implementación de cómo calcular algunos impuestos particulares.
Aquí está el patrón de estrategia:
- Usted define una interfaz, por ejemplo
TaxCalculation
, y su marco acepta instancias de este tipo para calcular impuestos
- Un usuario del marco crea una clase que implementa esta interfaz y la pasa a su marco, proporcionando así una forma de realizar parte de los cálculos.
No puede hacer lo mismo if/else
, porque eso requeriría cambiar el código del marco, en cuyo caso ya no sería un marco. Dado que los marcos a menudo se distribuyen en forma compilada, esta puede ser la única opción.
Aún así, incluso si solo escribe un código regular, la Estrategia es beneficiosa porque aclara sus intenciones. Dice "esta lógica es conectable y condicional", es decir, puede haber múltiples implementaciones que pueden variar según las acciones del usuario, la configuración o incluso la plataforma.
El uso del patrón de estrategia puede mejorar la legibilidad porque, si bien una clase que implementa una estrategia particular generalmente debe tener un nombre descriptivo, por ejemplo USAIncomeTaxCalculator
, los if/else
bloques no tienen nombre, en el mejor de los casos solo se comentan, y los comentarios pueden mentir. Además, para mi gusto personal, solo tener más de 3 if/else
bloques seguidos no es legible, y se vuelve bastante malo con los bloques anidados.
El principio Abierto / Cerrado también es muy relevante porque, como describí en el ejemplo anterior, la Estrategia le permite extender una lógica en algunas partes de su código ("abierto para extensión") sin reescribir esas partes ("cerrado para modificación" )