Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Este principio afirma que una clase debe estar abierta a extensin pero cerrada a
modificaciones. Esto lo que viene a decir es que nuestra aplicacin debera estar
diseada de manera que ante peticiones de cambio en la aplicacin, deberamos
ser capaces de aadir funcionalidad sin modificar la existente (siempre que sea
posible).
Como se puede observar en las relaciones dicha clase viene determinando por uno
de los estados de la enumeracin EstadoTarea (Pendiente, Finalizada, Cancelada),
adems se puede observar que la clase implementa 3 mtodos, Iniciar, Cancelar y
Finalizar que cambian si es posible el estado de la tarea. Veamos cmo sera una
posible implementacin del mtodo Finalizar.
Al parecer esta implementacin no est nada mal, de hecho no est nada mal si no
se agregarn nuevos estados, pero como comentamos al inicio, todas las
aplicaciones cambian durante su ciclo de vida.
Aparentemente, parece una modificacin trivial pero este cambio puede involucrar
muchos otros, en los mtodos y/o clases donde se utilice el EstadoTarea, no
olvidemos que este nuevo cambio nos hara modificar tambin la implementacin
del mtodo Cancelar.
Vemos claramente, por cada nuevo estado que implementemos tendremos que
identificar la implementacin para todas las clases que lo utilizan y modificarlas,
violando el principio Abierto/Cerrado (OCP).
A continuacin planteamos una solucin a la violacin del principio utilizando el
patrn State.
Bsicamente, lo que se ha hecho es crear una clase por cada estado en lugar de
tener una nica clase cuyos mtodos estn basados en sentencias condicionadas
por el estado de la tarea. Adems, con esta nueva implementacin se ha delegado
la responsabilidad de finalizar, cancelar o posponer a una nueva clase
BaseEstadoTarea que que se ha marcado como abstracta. La clase Tarea
implementar sus propios mtodos y delegar la responsabilidad a travs de las
clases TareasEstados que heredan de BaseEstadoTarea. Debido a que la clase
Tarea gira en torno a un estado, asumimos que el estado inicial por defecto es
Pendiente, y as se deber especificar en el constructor, instanciando a
TareaEstadoPendiente.
get {
return base.Ancho;
}
set {
base.Ancho = value;
base.Alto = value;
get {
return base.Alto;
set {
base.Ancho = value;
base.Alto = value;
return Ancho*Alto;
[TestFixture]
[Test]
Ancho = 5,
Alto = 2
};
Assert.AreEqual(10.0f, r.Area());
Por otro lado, Bertrand Meyer acu el Diseo por Contratos (DbC) en el que se
especifica un contrato a nivel de mtodo para establecer los valores/tipos
aceptables de entrada y de retorno, las condiciones de valor o de tipo para los
errores y excepciones que puedan ocurrir, la precondicin y pos condicin y las
invariantes.
Preservar la invariancia.
[Poscondicion("$after(Ancho)>0")]
[Poscondicion("$after(Alto)=$before(Alto)")]
Y el de Cuadrado:
[Poscondicion("$after(Ancho)>0")]
En primer lugar, la propia naturaleza de la clase Cuadrado implica, precisamente
para preservar la Invariancia, que la propiedad Ancho modifique, adems, la
propiedad Alto y esto deriva en que la postcondicin de Cuadrado para el setter sea
menos restrictiva que en Rectangulo y por tanto no cumpla con El Principio de
Substitucin de Liskov
El Principio de Segregacin de Interfaces fue utilizado por primera vez por Robert
C. Martin durante unas sesiones de consultora en Xerox. Por aquella poca, Xerox
estaba diseando una impresora multifuncional. El software diseado para la
impresora funcionaba y se adaptaba perfectamente a las necesidades iniciales de
la impresora; sin embargo, conforme fue evolucionando, y por lo tanto cambiando,
se hizo cada vez ms difcil de mantener. Cualquier modificacin tena un gran
impacto global sobre el sistema. La utilizacin de ISP permiti reducir los riesgos de
las modificaciones y otorg una mayor facilidad al mantenimiento. El ISP declara
que:
Interfaces "pesadas"
De "pesada" a confusa
Listado 2:
public interface IImprimible
{
void Imprimir();
}
public interface IFotocopiable
{
void Fotocopiar();
}
public interface IEscaneable
{
void Escanear();
}
public interface IFaxCompatible
{
void EnviarFax();
void RecibirFax();
}
public interface ITcpIpCompatible
{
void EnviarEMail();
}
class Modelo1998 : IImprimible, IEscaneable, IFaxCompatible
{
// ...
}
class Modelo2000 : IImprimible, IEscaneable, IFaxCompatible,
IFotocopiable
{
// ...
}
class Modelo2002 : IImprimible, IEscaneable, IFotocopiable,
ITcpIpCompatible
{
// ...
}
PRINCIPIO DE INVERSIN DE DEPENDENCIAS
A. Las clases de alto nivel no deberan depender de las clases de bajo nivel. Ambas
deberan depender de las abstracciones.
Pero entiendo que slo con esto no te quede muy claro de qu estamos hablando,
as que voy a ir desgranando un poco el problema, cmo detectarlo y un ejemplo.
Ejemplo
Imaginemos que tenemos una cesta de la compra que lo que hace es almacenar la
informacin y llamar al mtodo de pago para que ejecute la operacin. Nuestro
cdigo sera algo as:
Aqu estamos incumpliendo todas las reglas que impusimos al principio. Una clase
de ms alto nivel, como es la cesta de la compra, est dependiendo de otras de alto
nivel, como cul es el mecanismo para almacenar la informacin o para realizar el
mtodo de pago. Se encarga de crear instancias de esos objetos y despus
utilizarlas.
@Override
@Override