Читаючи статті про Інтернет-провайдера, схоже, є два суперечливих визначення ISP:
Згідно з першим визначенням (див. 1 , 2 , 3 ), ISP зазначає, що класи, що реалізують інтерфейс, не повинні змушувати реалізовувати функції, які їм не потрібні. Таким чином, жировий інтерфейсIFat
interface IFat
{
void A();
void B();
void C();
void D();
}
class MyClass: IFat
{ ... }
слід розділити на менші інтерфейси ISmall_1
іISmall_2
interface ISmall_1
{
void A();
void B();
}
interface ISmall_2
{
void C();
void D();
}
class MyClass:ISmall_2
{ ... }
оскільки таким чином мій MyClass
здатний реалізувати тільки ті методи, які необхідні ( D()
і C()
), не будучи змушений також забезпечити фіктивні реалізації для A()
, B()
і C()
:
Але згідно з другим визначенням (див. 1 , 2 , відповідь Назара Мерзи ), ISP стверджує, що для MyClient
виклику методів MyService
не слід знати про методи, MyService
які йому не потрібні. Іншими словами, якщоMyClient
потрібно лише функціональність C()
і D()
, то замість цього
class MyService
{
public void A();
public void B();
public void C();
public void D();
}
/*client code*/
MyService service = ...;
service.C();
service.D();
ми повинні відокремитись MyService's
методи в інтерфейсах, орієнтованих на клієнта :
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();
Таким чином, колишнє визначення, мета провайдера - " першим полегшити життя класів, що реалізують інтерфейс IFat ", тоді як з останньою метою ISP - " полегшити життя клієнтів, що викликають методи MyService ".
Яке з двох різних визначень провайдера насправді правильне?
@MARJAN VENEMA
1.
Отже, коли ви збираєтеся розділити IFat на менший інтерфейс, які методи в кінцевому підсумку, в якому ISmallinterface слід вирішити, виходячи з того, наскільки згуртовані члени.
Хоча має сенс розміщувати згуртовані методи в одному інтерфейсі, я вважав, що за допомогою шаблону ISP потреби клієнта мають перевагу над "згуртованістю" інтерфейсу. Іншими словами, я подумав, що з ISP ми повинні зв'язати в одному інтерфейсі ті методи, які потрібні певним клієнтам, навіть якщо це означає, що виключати з цього інтерфейсу ті методи, які, заради згуртованості, також повинні бути розміщені всередині того самого інтерфейсу?
Таким чином, якщо було багато клієнтів, яким потрібно буде коли-небудь зателефонувати CutGreens
, але не також GrillMeat
, тоді дотримуватися шаблону провайдера ми повинні лише вкладати CutGreens
всередину ICook
, але не також GrillMeat
, хоча ці два методи є дуже згуртованими ?!
2.
Я думаю, що ваша плутанина випливає з прихованого припущення в першому визначенні: що класи-реалізатори вже дотримуються принципу єдиної відповідальності.
Під "реалізацією класів, що не відповідають SRP" ви посилаєтесь на ті класи, які реалізують, IFat
або на класи, які реалізують ISmall_1
/ ISmall_2
? Я припускаю, що ви маєте на увазі класи, які реалізують IFat
? Якщо так, то чому ви вважаєте, що вони вже не дотримуються SRP?
Спасибі