2009-03-02 7 views
0

die Zusammenfassung meiner Frage ist "Ich habe 2 Klassen, die eine gemeinsame Schnittstelle haben, aber die beiden Klassen haben unterschiedliche Verhalten in Bezug auf ihre Eigenschaften. Eine Schnittstelle löst eine Ausnahme aus, wenn die Parameterwerte ungültig sind, der andere aktualisiert seinen internen Zustand Behandeln Sie die ungültigen Werte. Ist es in Ordnung, wenn die zwei Klassen dieselbe Schnittstelle verwenden oder sollten zwei Schnittstellen definiert werden, um dem Entwickler anzuzeigen, dass die beiden unterschiedliche Verhaltensweisen haben? "Ist es in Ordnung, dieselbe Schnittstellendefinition zu verwenden, aber ein anderes Verhalten zu bieten?

Ich werde versuchen, mit etwas Code zu klären. Ich habe die Schnittstelle unten definiert.

Und eine Klasse, die die Schnittstelle implementiert, wird diese Klasse verwendet, um den Ausgabeport auf einem digitalen IO-Board zu setzen.

 
public class DigitalStationAdapter : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get { return ports[stationId].Value; } 
     set { ports[stationId].Value = value; } 
    } 

    public void AddDigitalStation(string stationId, DigitalIoPort port) 
    { 
     ports.Add(stationId, port); 
    } 

    private IDictionary<string, DigitalIoPort> ports = new Dictionary<string, DigitalIoPort>(); 
} 

Ich habe auch ein Klassen, dass Datensätze welche Stationen Werte mussten geändert, so dass diese Änderungen an den digitalen IO propegated werden kann.

 
public class StationTransitions : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get 
     { 
      bool result = false; 

      if(changes.ContainsKey(stationId)) 
       result = changes[stationId]; 

      return result; 
     } 
     set 
     { 
      if(!changes.ContainsKey(stationId)) 
       changes.Add(stationId, value); 
      else 
       changes[stationId] = value; 
     } 
    } 

    public IDictionary GetChanges() 
    { 
     IDictionary<string, bool> result = changes; 

     changes = new Dictionary<string, bool> 

     return result; 
    } 

    private IDictionary<string, bool> changes = new Dictionary<string, bool>(); 
} 

So, während beide Klassen implementieren die gleiche Schnittstelle DigitalStationAdapter eine KeyNotFoundException werfen, wenn Sie versuchen, den Indexer mit einem StationID nicht im Wörterbuch zugreifen. In der Erwägung, dass StationTransitions erfolgreich sein werden, d. H. Unterschiedliches Verhalten. Ist das in Ordnung, dachte ich, dass Interfaces verwendet werden, um sowohl das Verhalten als auch die Struktur zu definieren?

Keith.

Antwort

2

Das ist in Ordnung. Stellen Sie sich Folgendes vor: Der Schlüssel zur Bestimmung, ob eine Vererbungsbeziehung "ok" ist, lautet Liskov substitution principle.. Dies erfordert, dass Code, der eine Basisklasse erwartet, in der Lage sein sollte, eine abgeleitete Klasse zu verwenden, ohne sie zu kennen. Dies bedeutet, dass die Voraussetzungen für eine Methode in einer abgeleiteten Klasse nicht gestärkt werden können, aber geschwächt werden können. Schnittstellen sind nur ein Spezialfall von Basisklassen.

In Ihrem Fall wäre die implizite Vorbedingung der Schnittstelle, dass die Eingabe gültig ist, wenn Sie sie definieren. Der gesamte Code, der die Basisklasse erwartet, sollte diese Voraussetzung annehmen und vermeiden, ungültige Daten zu übergeben oder bereit zu sein, mit der Ausnahme umzugehen. In der konkreten Klasse, die ihren internen Status aktualisiert, um mit der ungültigen Eingabe umzugehen, schwächen Sie eine Vorbedingung. Dies ist akzeptabel, soweit das Liskov-Substitutionsprinzip gilt.

Wenn Sie andererseits die Klasse erstellen würden, die automatisch mit der ungültigen Eingabe umgeht und keine Basisklasse wirft und die Klasse erstellt, die einen Nachkommen wirft, wäre das schlecht, weil Code die Basis erwartet Die Klasse konnte die abgeleitete Klasse nicht wie die Basisklasse verwenden. Es müsste über die abgeleitete Klasse wissen, um mit der möglichen Ausnahme umzugehen.

Verwandte Themen