2016-06-17 4 views
2

Ich glaube, die Frage ist selbsterklärend. Ich würde mich eher auf das Beispiel konzentrieren, um die Frage zu unterstützen.Schnittstelle Trennung Prinzip - Wie zu entscheiden, was zu trennen?

public interface IEnumerable 
{ 
    IEnumerator GetEnumerator(); 
} 

public interface ICollection : IEnumerable 
{ 
    void CopyTo(Array array, int index); 
    int Count { get; } 
    Object SyncRoot { get; } 
    bool IsSynchronized { get; } 
} 

public interface IList : ICollection 
{ 
    Object this[int index] { get; set; } 
    int Add(Object value); 
    bool Contains(Object value); 
    void Clear(); 
    bool IsReadOnly { get; } 
    bool IsFixedSize { get; } 
    int IndexOf(Object value); 
    void Insert(int index, Object value); 
    void Remove(Object value); 
    void RemoveAt(int index); 
} 

Es ist klar, dass IEnumerable getrennt ist nur über Sammlungen Looping zu ermöglichen. Aber ich verstehe nicht, warum sie ICollection und IList getrennt gehalten haben? Selbst wenn sie eins wären, würde IList nicht fett werden, weil dieses Verhalten immer von jeder Sammlung verlangt würde?

Ich stieß auf this Beitrag, der sagt, dass Ihre API IEnumerable zurückgeben würde, wenn Client nur Schleife der Elemente benötigt, ICollection, wenn nur Lesezugriff erforderlich war und so weiter.

Wie hat MSFT ISP so perfekt angewendet, dass es in all den Jahren nie Probleme verursacht hat?

Wird ISP einen fortlaufenden Prozess basierend auf Client-Code-Anforderungen oder einer einmaligen Anwendung anwenden? Wenn ISP nur einmal angewendet wird, dann ist meine Frage in dem Posttitel selbst.

+1

Ich bin nicht sicher, ob ich die .NET-Typen als Beispiele für Best Practices verwenden würde. –

+1

Basierend auf dem Beispiel würde ich fragen, warum IList nicht in zwei oder mehr Teile aufgeteilt wurde. Add + Remove könnte eine Stufe unterhalb der At- und der [] -Methode gewesen sein. –

Antwort

2

Ich verstehe nicht, warum sie ICollection und IList getrennt gehalten haben?

IList ist eine Sammlung, wo das Erlangen eines Artikels per Index logisch sinnvoll ist. Die Trennung in eine Unterschnittstelle erfolgt in der Erkenntnis, dass andere Sammlungen existieren, für die eine Indexierung nicht definiert ist. ISet ist ein Beispiel für eine solche Sammlung.

Merging ICollection und IList hätte negative Auswirkung auf die Fähigkeit eines Menschen ISet in einer sauberen Art und Weise zu definieren, da diese vier Methoden implementieren zu müssen:

this[int index] 
int IndexOf(Object value) 
void Insert(int index, Object value) 
void RemoveAt(int index) 

Auf der anderen Seite könnte man argumentieren, vernünftig, dass Methoden

int Add(Object value); 
bool Contains(Object value); 
void Clear(); 
bool IsReadOnly { get; } 
bool IsFixedSize { get; } 
void Remove(Object value); 

könnte zu ICollection Schnittstelle gehören

Schnittstelle Trennung Prinzip - Wie zu entscheiden, was zu trennen?

Die Entscheidung, was zu trennen ist, ist im Nachhinein viel einfacher, wenn die Klassen vorhanden sind. Sehen Sie nach, ob eine Klasse eine nicht implementierte Ausnahme auslösen muss. Diese Methoden sind Hauptkandidaten, die in eine Subschnittstelle verschoben werden, die eingeführt werden muss.

Betrachten Sie beispielsweise das Starten eines Entwurfs mit IList Methoden, die in ICollection verschoben wurden, und keine IList Unterschnittstelle. Mit diesen beiden Schnittstellen können Sie List und LinkedList Klassen erfolgreich erstellen.

Jetzt überlegen, HashSet zu der Mischung hinzuzufügen. Diese Klasse muss vier Methoden implementieren, die bei einer Set-Auflistung fehl am Platz sind. Daher sollten Sie eine oder zwei Sub-Schnittstellen hinzufügen - eine für Listen und eine weitere für Sets.

Es ist viel schwieriger, sich über die Trennung zu entscheiden, bevor Sie irgendwelche Klassen eingerichtet haben, da Ihre Schnittstelle die Anforderungen einer bestimmten Klasse erfüllt, die sie verwenden muss. Es ist nicht ungewöhnlich, mit einer flachen Schnittstellenstruktur zu beginnen und diese durch Refactoring in nachfolgenden Releases zu erweitern.

+0

Cool, es wird mir jetzt klarer. Aktuelle Frage - * Interface Segregation Prinzip - Wie zu entscheiden, was zu trennen? * Wichtige Punkte, die man sich bei ISP denken sollte? – niksofteng

+1

Ich denke, der deutlichste "Geruch" der ISP-Verletzung und klare Aufforderungen, wie zu entscheiden, was zu trennen ist, ist, wo eine Klasse eine Schnittstelle implementiert und eine oder mehrere der Methoden endet eine "NotImplementedException", wie es nur betroffen ist mit bestimmten Teilen der Schnittstelle. –

+0

@ Think2ceCode1ce Alternativ können Sie sehen, was Sie darstellen möchten - d. H. Konzepte von Menge/endliche Menge/geordnete endliche Menge im Falle dieser speziellen Frage. –

Verwandte Themen