Siguiendo con la linea de post que presentan los principios que componen marco de buenas prácticas SOLID. El que vamos a desarrollar en este post es el «Open Close Principle», esto hace referencia a que el código que desarrollamos debería estar abierto a ser extendido y cerrado a las modificaciones.
Sin más, veamos el ejemplo que vamos a desarrollar en este post:
Supongamos que estamos desarrollando un sistema para un almacen, en el cual se manejan productos. Estos productos, poseen características, las cuales pueden ser:
En donde los «Enums» mostrados poseen los siguientes elementos:
Digamos que por necesidad del negocio, nos vemos obligados a filtrar los productos que vamos almacenando por su color, teniendo esto en mente, creamos una nueva clase que llamaremos «ProductFilter».
De este modo, si queremos filtrar un grupo de colores, por un color en particular deberíamos hacer algo muy similar a esto:
De este modo, tenemos 3 productos, los cuales se agregan a una lista y esta lista se proporciona al método de filtrado que hemos creado. Si ejecutamos esta aplicación, tenemos el siguiente resultado:
Como podemos ver, se ejecuta sin problemas. El problema viene cuando requerimos realizar más filtros. Digamos que ahora nos indican que el filtrado también sea por tamaño, o por color y tamaño, terminariamos llenando nuestra clase «ProductFilter» de métodos. Algo muy similar a esto:
Como ven, esto rompe claramente el principio de Open Close Principle. Deberíamos de poder extender nuestros filtros, sin afectar la clase que ya se tiene, esto se puede conseguir a través de interfaces. En este caso, para respetar este principio voy a usar el «specification pattern». Veamos como podemos implementarlo y respetar este principio.
Es necesario creas dos interfaces para poder llevar a cabo la implementación de este patrón de diseño, siendo la primera una que nos permitirá definir la especificación, cuando esta va a estar satisfecha y el tipo de elemento que recibe como tipo de entrada y la segunda espara implementar el filtro y como este se lleva a cabo.
Ahora, implementemos el primero de los filtros, este es es el «ColorSpecification»:
Como pueden ver, implementamos la interfaz definida en el paso anterior, tenemos una variable que se inicializa en el constructor, que para el filtro es el color y en el método «IsSatisfied» solo se retorna true si el color del producto que nos proporcionan es igual al que se inicializa en el constructor.
Para poder usar este filtro es necesario implementar también la interfaz «IFilter», lo cual realizamos del siguiente modo:
Del mismo modo que en la implementación anterior, se se le indica el tipo de elemento con el cual se desea filtrar, iteramos sobre la lista de estos elementos y solo solo cuando la especificación haya sido satifecha retornamos, el «yield» lo usamos por la eficiencia en el recorrido de nuestra lista.
Veamos como usamos este filtro en nuestra clase principal y que resultado obtenemos:
Finalmente, mostrare como se puede realizar el más de un filtro a la vez, para ejemplificar esto, creare un filtro por tamaño, siguiendo el mismo esquema ejemplificado anteriormente. Para poder adicionar más de un filtro es necesario crear una nueva clase pero ahora su tipo también será genérico, del siguiente modo:
Inicializamos dos variables en el constructor, ambas del tipo «ISpecification», y sólo se satisface cuando ambas variables lo están. Para consumir este método, debemos de hacerlo del siguiente modo:
Se le tienen que indicar los filtros que se quieren realizar y al consumir este filtro en el cual buscamos un producto del color verde y de tamaño pequeño, nuestro resultado es el siguiente:
Espero que les ayude a entender un poco más este principio, así mismo comentarles que este es el segundo post de los principios que componen SOLID. Como siempre, dejo el video del desarrollo de esta post y el link al repositorio en github.
REPO: GITHUB
Listado de POST sobre SOLID anteriores:
Deja un comentario