Al leer artículos sobre ISP, parece haber dos definiciones contradictorias de ISP:
Según la primera definición (ver 1 , 2 , 3 ), el ISP establece que las clases que implementan la interfaz no deberían verse obligadas a implementar funcionalidades que no necesitan. Por lo tanto, interfaz gruesaIFat
interface IFat
{
void A();
void B();
void C();
void D();
}
class MyClass: IFat
{ ... }
debe dividirse en interfaces más pequeñas ISmall_1
yISmall_2
interface ISmall_1
{
void A();
void B();
}
interface ISmall_2
{
void C();
void D();
}
class MyClass:ISmall_2
{ ... }
ya que de esta manera my MyClass
puede implementar solo los métodos que necesita ( D()
y C()
), sin verse obligado a proporcionar implementaciones ficticias para A()
, B()
y C()
:
Pero de acuerdo con la segunda definición (ver 1 , 2 , respuesta de Nazar Merza ), el ISP afirma que MyClient
llamar a los métodos MyService
no debe ser consciente de los métodos MyService
que no necesita. En otras palabras, si MyClient
solo necesita la funcionalidad de C()
y D()
, en lugar de
class MyService
{
public void A();
public void B();
public void C();
public void D();
}
/*client code*/
MyService service = ...;
service.C();
service.D();
debemos segregar los MyService's
métodos en interfaces específicas del cliente :
public interface ISmall_1
{
void A();
void B();
}
public interface ISmall_2
{
void C();
void D();
}
class MyService:ISmall_1, ISmall_2
{ ... }
/*client code*/
ISmall_2 service = ...;
service.C();
service.D();
Por lo tanto, con la primera definición, el objetivo del ISP es " facilitar la vida de las clases que implementan la interfaz IFat ", mientras que con la segunda, el objetivo del ISP es " facilitar la vida de los clientes que llaman métodos de MyService ".
¿Cuál de las dos definiciones diferentes de ISP es realmente correcta?
@MARJAN VENEMA
1)
Entonces, cuando va a dividir IFat en una interfaz más pequeña, qué métodos terminan en qué ISmallinterface debe decidirse en función de la cohesión de los miembros.
Si bien tiene sentido colocar métodos cohesivos dentro de la misma interfaz, pensé que con el patrón ISP las necesidades del cliente tienen prioridad sobre la "cohesión" de una interfaz. En otras palabras, pensé que con ISP deberíamos agrupar dentro de la misma interfaz aquellos métodos necesarios para clientes particulares, incluso si eso significa dejar fuera de esa interfaz aquellos métodos que, por el bien de la cohesión, también deberían ponerse dentro de esa misma interfaz.
Por lo tanto, si había muchos clientes que solo necesitarían llamar CutGreens
, pero no también GrillMeat
, entonces, para adherirnos al patrón de ISP, ¿solo deberíamos ponerlos CutGreens
dentro ICook
, pero no también GrillMeat
, a pesar de que los dos métodos son altamente cohesivos?
2)
Creo que su confusión se deriva de una suposición oculta en la primera definición: que las clases implementadoras ya están siguiendo el principio de responsabilidad única.
Al "implementar clases que no siguen SRP", ¿se refiere a las clases que implementan IFat
oa las clases que implementan ISmall_1
/ ISmall_2
? ¿Asumo que te refieres a clases que implementan IFat
? Si es así, ¿por qué supone que no siguen SRP?
Gracias