Ist es besser, eine * Schnittstelle * oder ein * Objekt * als Parameter an eine Funktion zu übergeben?
-
05-07-2019 - |
Frage
Ich versuche, einen Kollegen zu überzeugen, dass eine Funktion eine Schnittstelle als Parameter übernehmen sollte, und nicht das Objekt selbst. Ich denke, kleine Gegenstände in Ordnung sein kann über passieren, aber für große diejenigen, würde ich ihnen eine Schnittstelle geben und geben nur die I / F über, nicht das Ganze.
Beachten Sie, dass es jemals nur eine dieser großen Klassen - die i / f nie für ein anderes Objekt verwendet werden. Dies ist lediglich für die Umsetzung eines Objekts zu verbergen.
Würden Sie zustimmen, dass eine große Klasse in eine Schnittstelle zu trennen (n) ist eine gute Praxis?
Gibt es irgendwelche Nachteile dies zu tun?
Beispiel:
public interface class IVeryLargeClass
{
void DoSomething();
...
};
public ref class VeryLargeClass : public IVeryLargeClass
{
public:
virtual void DoSomething() { ... }
...
};
public ref class AnotherClass
{
public:
AnotherClass(VeryLargeClass^ vlc) { vlc->DoSomething(); }
// OR
AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};
Lösung
Eine der ersten Prinzipien, die Sie in OO Entwicklung erfahren:
Programm auf eine Schnittstelle, nicht ein Umsetzung.
Sie zeigen, dass „es wird immer nur eine dieser großen Klassen - der i / f nie für ein anderes Objekt verwendet werden“. Dies könnte in Ihrem Fall zutreffen, aber ich wünschte, ich für jedes Mal ein Nickel hatte eine solche Aussage als falsch herausgestellt hat.
Neben der Frage, ob es möglicherweise mehrere Implementierungen von Ihrer Schnittstelle sein, sollten Sie auch prüfen, ob Ihre konkreten Objekt Exporte (oder exportieren könnten) zusätzliche Methoden, die mit den Operationen in der Schnittstelle deklariert keine logische Affinität teilen. In einem solchen Fall könnten Sie einfach die zusätzlichen Operationen in einem oder mehreren zusätzlichen Schnittstellen deklarieren. Ein Client, dann benötigen nur wenige mit der Schnittstelle, die die Operationen, in denen exportiert sie interessiert ist.
Einfach gesagt, bietet Schnittstellen ein Mittel, um die Kopplung zwischen Kunden und Anbietern zu verwalten.
Andere Tipps
Die Dependency Inversion Principle können wie folgt zusammengefasst werden: Es ist besser, hängen von Abstraktionen als concretions.
Es ist fast immer besser, eine Schnittstelle zu übergeben, als es eine konkrete Klasse übergeben ist.
Das heißt, hohe Kohäsivität gegen interne Typen ist in Ordnung innerhalb eines bestimmten Moduls, aber das ist sehr subjektiv, wann und wie sollten Sie konkrete Objekte übergeben.
Ich würde es vorziehen, im Interesse der Schaffung einer Schnittstelle zu schaffen und Schnittstelle zu vermeiden. Wenn Sie diese Schnittstelle in mehr als ein Ort verwenden können, dann haben Sie einen Gewinner - oder ob dies eine öffentliche Funktion und Klasse ist, und Sie mögen speziell vereinfachen
.Wenn Sie übergeben eine Implementierung, Sie Art von losem einer der Vorteile von Schnittstellen, dh die Logik von der eigentlichen Implementierung zu trennen.
Die Schnittstelle eines Softwaremoduls A absichtlich gehalten wird von der separaten Umsetzung dieses Moduls. Das Letztere enthalten den eigentlichen Code des Verfahren und Methoden beschrieben, in Die Schnittstelle, sowie andere "Privates" Variablen, Prozeduren, etc .. Jede andere Softwaremodul B (die bezeichnet als Client A sein), dass wirkt mit einem gezwungen ist, dies zu tun nur über die Schnittstelle. Ein praktische Vorteil dieses Anordnung besteht darin, dass die ersetzende Umsetzung einer durch ein anderes dass entspricht die gleichen Spezifikationen Die Schnittstelle sollte nicht dazu führen, B Ausfall solange seine Verwendung von A erfüllt mit den Spezifikationen von Schnittstelle (siehe auch Liskov Substitutionsprinzip).
Das andere Problem ist Ihre ganz große Klasse selbst. Dies kann nicht in den Rahmen dessen, was Sie tun, aber eine sehr große Klasse bedeutet, dass es in erster Linie zu viel tun könnte. Können Sie Refactoring in kleinere jeweiligen Kategorie es, wo die Informationen innerhalb der Funktion erforderlich Sie anrufen in seiner eigenen kleineren Klasse gekapselt ist? Wenn Sie eine Schnittstelle gegen diese Klasse erstellen können Sie es, dass viel mehr wiederverwendbar als gegen die sehr große Klasse finden Sie im Moment haben.