Principios de diseño, ¿Los tenemos en cuenta?

En este articulo me pareció interesante repasar algunos principios de diseño desde la óptica de componentes, particularmente que son para mi punto de vista son "no negociables" en la ingenieria de software.

Hay cuatro principios básicos de diseño aplicables al diseño al nivel de componentes y se han adoptado ampliamente cuando se aplica ingenieria de software orientada a objetos. La idea es lograr diseños que sean más sensibles al cambio y reducir la propagación de efectos secundarios cuando ocurren cambios.

El objetivo del artículo es cubrir uno de los principios nombrados, "el principio abierto-cerrado (PAC)".

¿Qué dice este principio?

"El componente de un módulo debe estar abierto para la extensión, pero cerrado para modificación"

Para expresarlo de manera simple, el diseñador debe especificar el componente de manera que permita extenderlo (dentro del dominio funcional que atiende) sin necesidad de modificaciones internas al propio componente (al nivel de código o lógica).

Caso normal, tenemos declarada un clase "Validador" que realiza revisiones sobre el estado de un objeto "Documento", si nuestra implementación es del tipo "if then" para determinar el documento a operar y el validador no solo atiende documento, sino que se amplía a "documento gerencial", "documento de calidad", etc, se requerirá lógica de procesamiento interno adicional, una clara violación al PAC.

Ahora miremos la siguiente propuesta:


De esta forma tenemos un diseño que no viola el principio PAC y es sensible a la extensión.

¿Cómo lo podemos implementar?

Para este ejemplo realicé una implementación de un componente de WCF (en C#) donde el servicio de validación expone la interface "IDocumento" como contrato para ser consumida por un client.

Veamos el code:

La interface

[ServiceContract]


public
interface
IDocumento

{

[OperationContract]


bool ConfirmarEstado();

}

La clase


public
class
Documento:IDocumento

{

#region IDocumento Members



public
bool ConfirmarEstado()

{


return
true;

}


#endregion

}

Muy simples implementaciones del validador.

Configuración del host que brinda el servicio de validador:

<system.serviceModel>

<services>

<service
name="ServicioDeValidacion.Documento"
behaviorConfiguration="metadataBehavior">

<endpoint
address="ServicioValidador"
binding="basicHttpBinding"
contract=" ServicioDeValidacion.IDocumento"></endpoint>

<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"></endpoint>

<host>

<baseAddresses>

<add
baseAddress="http://localhost:8000/Validador/"/>

<add
baseAddress="net.tcp://localhost:8010/ Validador /"/>

</baseAddresses>

</host>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior
name="metadataBehavior">

<serviceMetadata
httpGetEnabled="true"/>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

De esta forma tenemos nuestro servicio configurado para la utilización soportando un esquema extensible, sin violar el PAC y con una implementación básica de servicio.

En próximos artículos veremos los demás principios, y les dejo un interrogante importante ¿Hacemos ingenieria de software? ....

Espero les sea de utilidad…

Bibliografía: Ingenieria del Software – Un enfoque práctico - Pressman

Entradas más populares de este blog

TensorFlow, una simple aproximación al calculo numérico en Python

7 arquetipos #Polymer 1.0 puntos esenciales prácticos

Iniciando la representación de una mobile-web-page pensando en el rendimiento - Parte 1