2013-07-10 9 views
6

Czy dziedziczenie z klasy z nieużywanymi metodami narusza zasadę segregacji interfejsu?Zasada podziału na dziedziczenie i interfejs

Na przykład:

abstract class Base 
{ 
    public void Receive(int n) 
    { 
     // . . . (some important work) 

     OnMsg(n.ToString()); 
    } 

    protected abstract void OnMsg(string msg); 
} 

class Concrete : Base 
{ 
    protected override void OnMsg(string msg) 
    { 
     Console.WriteLine("Msg: " + msg); 
    } 
} 

Concrete zależy od sposobu Base.Receive(int n), ale nigdy nie używa.

UPD

Definicja używam:

ISP stwierdza, że ​​klient nie powinien być zmuszony polegać na metodach to nie używają.

+0

nie jestem pewien, że w tym przykładzie, że nie używa go, w jaki sposób OnMsg kiedykolwiek nazwać jeśli Otrzymuj jest nieużywany? – BlackICE

+0

W moim przypadku jedynym sposobem na wywołanie 'OnMsg' jest od' Receive'. Potrzebuję tego dziedziczenia, aby projektować przychodzące dane ('int n') do interfejsu' Concrete', który używa 'ciągu msg'. W prawdziwym przykładzie jest trochę bardziej skomplikowana praca niż tylko 'ToString()' – astef

+0

@astef: Jak słusznie zauważył Paulo, używasz 'wzoru szablonu' tutaj :) –

Odpowiedz

7

Myślę, że źle rozumiesz, co mówi zasada podziału na interfejsy. W twoim przypadku wszystko jest w porządku i nie "wymuszasz" żadnej implementacji. W rzeczywistości starasz się Template method design pattern

Jeśli miał hipotetyczny

interface ICommunicateInt 
{ 
    int Receive(); 
    void Send(int n); 
} 

w celu jej wdrożenia, klasa Base byłby zmuszony do wprowadzenia Send sposób, że nie potrzebują. Tak, ISP sugeruje, że lepiej jest mieć:

interface ISendInt 
{ 
    void Send(int n); 
} 

interface IReceiveInt 
{ 
    int Receive(); 
} 

dzięki czemu zajęcia mogą zdecydować się na wprowadzenie jednego lub obu. Również metody w innych klasach, które potrzebują klasy, który można wysłać int, może wymagać

void Test(ISendInt snd) 
// void Test(ICommunicateInt snd) // Test would "force" snd to depend on 
            // a method that it does not use 
0

Nie widzę, że Beton "zależy" od Base.Receive() w sposób będę używać tego terminu. W jaki sposób Beton musiałby się zmienić, gdyby zmiana została zmodyfikowana? Nie kłóciłbym się wcale. Przypuśćmy, że zastąpiliśmy Receive() metodą o innej nazwie lub innym podpisem, Beton byłby nieświadomy. Czy Concrete wywołuje funkcję Receive()? Nie. Nie widzę zależności od funkcji Receive() tutaj.

Zależność jest zależna od podpisu OnMsg(), Konkretny bierze udział w bardzo szczególnej relacji z Bazą, spełniając tę ​​umowę OnMsg().

Jednak w bardzo różnym sensie beton bardzo zależy od Base.Receive(), który jest jego interfejsem ze światem zewnętrznym - bez tej metody nikt nie ma dostępu do możliwości firmy Concrete. W tym sensie Beton "używa" Base.Receive() na bardzo podstawowym poziomie.

+0

Rozumiem cię. Ale jaka jest odpowiedź? Czy to zły sposób na wyświetlanie nieznanych danych przychodzących do interfejsu docelowego? – astef

+0

Nie, nie jest źle, to bardzo ważny wzór. – djna