Ao ler artigos no ISP, parece haver duas definições contraditórias do ISP:
De acordo com a primeira definição (consulte 1 , 2 , 3 ), o ISP afirma que as classes que implementam a interface não devem ser forçadas a implementar funcionalidades de que não precisam. Assim, interface gordaIFat
interface IFat
{
void A();
void B();
void C();
void D();
}
class MyClass: IFat
{ ... }
deve ser dividido em interfaces menores ISmall_1
eISmall_2
interface ISmall_1
{
void A();
void B();
}
interface ISmall_2
{
void C();
void D();
}
class MyClass:ISmall_2
{ ... }
pois desta forma o meu MyClass
é capaz de implementar apenas os métodos de que necessita ( D()
e C()
), sem ser forçado a também fornecer implementações dummy para A()
, B()
e C()
:
Mas, de acordo com a segunda definição (ver 1 , 2 , resposta de Nazar Merza ), o ISP afirma que MyClient
chamar métodos MyService
não deve estar ciente de métodos MyService
que não precisam. Em outras palavras, se MyClient
apenas precisar da funcionalidade de C()
e D()
, em vez de
class MyService
{
public void A();
public void B();
public void C();
public void D();
}
/*client code*/
MyService service = ...;
service.C();
service.D();
devemos separar MyService's
métodos em interfaces específicas do 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();
Assim, com a definição anterior, o objetivo do ISP é " facilitar a vida das classes implementando a interface IFat ", enquanto que com a última, o objetivo do ISP é " facilitar a vida dos clientes que chamam métodos do MyService ".
Qual das duas definições diferentes de ISP está realmente correta?
@MARJAN VENEMA
1
Então, quando você vai dividir o IFat em uma interface menor, quais métodos acabam em que ISmallinterface deve ser decidido com base na coesão dos membros.
Embora faça sentido colocar métodos coesos na mesma interface, pensei que, com o padrão ISP, as necessidades do cliente têm precedência sobre a "coesão" de uma interface. Em outras palavras, pensei que, com o provedor de serviços de Internet, deveríamos agrupar na mesma interface os métodos necessários para determinados clientes, mesmo que isso signifique deixar de fora dessa interface os métodos que deveriam, por uma questão de coesão, também serem colocados nessa mesma interface?
Assim, se havia muitos clientes que apenas precisavam ligar CutGreens
, mas não também GrillMeat
, para aderir ao padrão de ISP, devemos colocar apenas CutGreens
dentro ICook
, mas não também GrillMeat
, mesmo que os dois métodos sejam altamente coesos ?!
2)
Penso que a sua confusão deriva da suposição oculta na primeira definição: que as classes de implementação já estão seguindo o princípio da responsabilidade única.
Ao "implementar classes que não seguem o SRP", você está se referindo às classes que implementam IFat
ou às classes que implementam ISmall_1
/ ISmall_2
? Presumo que você esteja se referindo a classes que implementam IFat
? Se sim, por que você acha que eles ainda não seguem o SRP?
obrigado