Durante la lettura di articoli su ISP, sembrano esserci due definizioni contraddittorie di ISP:
Secondo la prima definizione (vedi 1 , 2 , 3 ), l'ISP afferma che le classi che implementano l'interfaccia non dovrebbero essere costrette ad implementare funzionalità di cui non hanno bisogno. Quindi, fat interface IFat
interface IFat
{
void A();
void B();
void C();
void D();
}
class MyClass: IFat
{ ... }
dovrebbe essere diviso in interfacce più piccole ISmall_1
e ISmall_2
interface ISmall_1
{
void A();
void B();
}
interface ISmall_2
{
void C();
void D();
}
class MyClass:ISmall_2
{ ... }
in questo modo il mio MyClass
è in grado di implementare solo i metodi di cui ha bisogno ( D()
e C()
), senza essere costretti a fornire anche implementazioni fittizie per A()
, B()
e C()
:
Ma secondo la seconda definizione (vedi 1 , 2 , risposta di Nazar Merza ), ISP afferma che MyClient
chiama i metodi su MyService
shouldn ' t essere a conoscenza dei metodi su MyService
di cui non ha bisogno. In altre parole, se MyClient
richiede solo la funzionalità di C()
e D()
, allora invece di
class MyService
{
public void A();
public void B();
public void C();
public void D();
}
/*client code*/
MyService service = ...;
service.C();
service.D();
dovremmo separare i metodi MyService's
in interfacce specifiche del client :
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();
Quindi con la precedente definizione, l'obiettivo dell'ISP è " rendere più facile la vita delle classi che implementano l'interfaccia IFat ", mentre con quest'ultimo l'obiettivo dell'ISP è di " vita dei client che chiamano i metodi di MyService più semplici ".
Quale delle due diverse definizioni di ISP è effettivamente corretta?
@MARJAN VENEMA
1.
So when you are going to split IFat into smaller interface, which methods end up in which ISmallinterface should be decided based on how cohesive the members are.
Anche se è logico mettere metodi coesivi all'interno della stessa interfaccia, ho pensato con il modello ISP che le esigenze del cliente hanno la precedenza sulla "coesione" di un'interfaccia. In altre parole, pensavo che con l'ISP dovremmo raggruppare all'interno della stessa interfaccia quei metodi necessari a particolari client, anche se ciò significa lasciare fuori da quell'interfaccia quei metodi che dovrebbero, per motivi di coesione, essere inseriti all'interno della stessa interfaccia?
Quindi, se ci sono molti clienti che hanno solo bisogno di chiamare CutGreens
, ma non anche GrillMeat
, quindi per aderire al pattern ISP dovremmo solo mettere CutGreens
dentro ICook
, ma non anche GrillMeat
, anche se i due metodi sono altamente coesivi ?!
2.
I think that your confusion stems from the a hidden assumption in the first definition: that the implementing classes are already following the single responsibility principle.
Con "implementare le classi che non seguono SRP" ti riferisci a quelle classi che implementano IFat
o alle classi che implementano ISmall_1
/ ISmall_2
? Presumo che ti riferisci alle classi che implementano IFat
? In tal caso, perché ritieni che non seguano già SRP?
grazie