Skip to content

Open Close Principle

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:

Clase de Productos

En donde los “Enums” mostrados poseen los siguientes elementos:

Clase de Enums

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:

Filtro por color los productos

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:

Filtrado por color a los productos
Filtrado Correcto

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:

Llenado de métodos para diversos tipos de filtros

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.

Interfaz IFilter
Interfaz ISpecification

Ahora, implementemos el primero de los filtros, este es es el “ColorSpecification”:

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:

Implementación del IFilter

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:

Uso del filtro
Resultado del nuevo filtrado

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:

AndSpecification para realizar más de un filtro

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:

Consumiendo más de un filtro a la vez

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:

Resultado de ambos filtros

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:

Published inNetCore

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *