Was zuerst kommt - Die Schnittstelle oder die Klasse

8

Während der Entwicklung neuer Funktionen in Ihrer Software ist dieser Prozess die beste Vorgehensweise

  1. Entwerfen Sie die Schnittstelle, die die Klasse implementieren wird.
  2. Schreiben der Klasse und späteres Extrahieren der Schnittstelle.

Wenn Sie die Route Nummer 2 wählen, wann entscheiden Sie, dass eine Schnittstelle benötigt wird?

    
David Williams 13.03.2009, 17:54
quelle

16 Antworten

16

Die Benutzeroberfläche wird angezeigt, wenn Sie allgemeine Funktionen aus mehreren Klassen umstrukturieren müssen.

Bis Sie mehrere Klassen mit gemeinsamen Funktionen haben, ist es schwer vorauszusehen, wie die Schnittstelle aussehen sollte.

Sobald Sie ein paar Klassen haben, ist es sehr viel einfacher, herauszufinden, was die Schnittstelle sein muss. Gehen Sie dann zurück und refactorieren Sie diese Klassen, um die neu entdeckte Schnittstelle richtig zu implementieren.

Einige Leute entwerfen viele Klassen auf Papier, um herauszufinden, was die Schnittstellen sein sollten. Speichert das Refactoring von echtem Code. Stattdessen müssen Sie Ihr Design umgestalten.

    
S.Lott 13.03.2009, 17:57
quelle
6

Trickfrage! Der Test kommt zuerst. Dann die Implementierung für den Test, die eine Klasse ist, die eine Schnittstelle bereits implementieren kann oder nicht. Ein Teil des Testdurchlaufs kann das Extrahieren einer Schnittstelle aus einer vorhandenen Klasse beinhalten, aber versuchen Sie nicht zu erraten, was Ihre Schnittstelle benötigen wird, bevor Sie etwas haben, das diese Schnittstelle benötigt.

Du wirst dich selbst verrückt machen, wenn du versuchst, das im Voraus herauszufinden - oder jedenfalls immer in meinen Tagen vor TDD. Entscheiden Sie, welche Funktionalität Ihre App benötigt, schreiben Sie einen Test und lassen Sie sich testen, was Sie mit Ihrem Code tun.

    
Brian Guthrie 13.03.2009 18:59
quelle
3

Ich stimme Brian Guthrie zu. Der Test kommt zuerst, weil er dein Design antreibt. Während dies normalerweise bedeutet, dass Sie mit einer konkreten Klasse enden (die, die Sie entwerfen, indem Sie ihr Verhalten in einer Reihe von Tests angeben), werden Abhängigkeiten normalerweise mittels Schnittstellen ausgedrückt (um Spott zu machen und dem Dependency Inversion-Prinzip ).

Das bedeutet oft, dass Sie die Schnittstellen haben, bevor Sie die Klassen haben, aber nur, weil Sie früher brauchen.

    
Nils Wloka 13.03.2009 20:19
quelle
2

Ich gehe normalerweise mit der zweiten Option. Schreiben Sie später eine Klasse und extrahieren Sie die Schnittstelle. In der Regel ist der Grund für das Extrahieren einer Schnittstelle die Notwendigkeit einer zweiten Implementierung dieser Schnittstelle (oft als Nachahmung für Komponententests)

    
Bradley Harris 13.03.2009 18:09
quelle
1

Ich würde sagen, dass die Schnittstellen an erster Stelle stehen, aber sie kommen auf, wenn Sie eine bestimmte Klasse / Methode entwickeln. Wenn Sie einen Punkt treffen, von dem Sie wissen, dass Sie von einer anderen Klasse / Methode abhängig sind, verwenden Sie eine Schnittstelle, um die Abhängigkeit hinzuzufügen und Ihren Code weiter zu schreiben. Gehen Sie dann zurück, nachdem Sie die aktuelle Komponente geschrieben und die Komponenten erstellt haben, die die benötigten Schnittstellen implementieren.

    
Chris Shaffer 13.03.2009 18:00
quelle
1

Alles hängt von der Situation ab ...

Wenn Sie in der Design-Phase wissen, dass Sie mehrere Klassen haben, die die gleiche "Gemeinsamkeit" haben, deren Implementierung jedoch unterschiedlich ist, dann steht die Oberfläche an erster Stelle.

Software ist jedoch organisch; Es entwickelt sich ständig weiter, so dass ich mir vorstellen kann, dass Sie in einigen Fällen eine Klasse haben und nach einiger Zeit eine Schnittstelle aus dieser Klasse extrahieren müssen.

    
Frederik Gheysels 13.03.2009 18:01
quelle
1

Letztendlich sollte Ihre Entwurfsphase unabhängig von Ihrer Implementierungsphase sein. Bevor Sie mit dem Codieren beginnen, sollten Sie sich ein genaues Bild davon machen, wie die Interaktionen zwischen Ihren Klassen aussehen werden, und hoffentlich werden Ihre Schnittstellenentscheidungen daraus ersichtlich.

Wenn Sie jedoch bereits eine Klasse geschrieben haben und diese nun umgestalten müssen, um eine Schnittstelle zu haben, dann beachten Sie, dass die Schnittstelle einfach eine Reihe von Funktionen / Methoden auswählt, die einen gemeinsamen Zweck haben, der benötigt wird von mehr als einer Klasse. Wenn Sie feststellen, dass es einige nützliche Funktionen für Ihre anderen Klassen gibt, dann wären diese Methoden gute Kandidaten für eine Schnittstelle.

Ein weiterer Teil der Schnittstellen, der sie wirklich nützlich macht, ist, wenn Sie feststellen, dass es bestimmte Teile Ihrer Klasse gibt, die nicht privat sind, sondern von bestimmten anderen Objekten verborgen werden sollen. In diesem Fall können Sie die Funktionen übernehmen offenbaren wollen und sie zu einer Schnittstelle machen.

Ich stimme stark mit niemandem überein, der sagt, dass Sie nicht vorher entwerfen sollten. Codierer lieben es, direkt hinein zu springen, und manchmal ist ein Refactoring notwendig, aber eine starke Designphase wird später viel Zeit für das Refactoring einsparen.

    
DevinB 13.03.2009 18:47
quelle
1

Bei den meisten Klassen ist das Interface wirklich wichtig, da die Implementierung jederzeit geändert werden kann, aber sobald etwas in der Oberfläche bereitgestellt wird, ist es schwierig oder unmöglich, es zurückzuziehen. Für den Rest des Projekts ist die Schnittstelle entscheidend, und die Implementierung ist das Problem eines anderen.

Idealerweise werden die Hauptmerkmale der Schnittstelle vor jeder Implementierung spezifiziert. (Es ist eine gute Idee, auch Tests im Voraus zu entwickeln.) Die Details können sich weiterentwickeln, aber alle Änderungen an der Schnittstelle sollten auf dem basieren, was andere Klassen und Routinen benötigen, und nicht auf Artefakten der Implementierung. Die Implementierung sollte immer von der Schnittstelle bestimmt werden, nicht umgekehrt.

(Da dies eine sprachunabhängige Frage ist, gehe ich davon aus, dass es sich bei der diskutierten "Schnittstelle" um die öffentliche Funktionalität der Klasse handelt und nicht etwa um Java als Ersatz für abstrakte C ++ - Klassen. In C ++ wäre das so die Teile der Klassendefinition als "public" markiert.)

    
David Thornley 13.03.2009 19:38
quelle
0

Nun, wenn Sie wirklich die Design-Phase durchlaufen haben, haben Sie die Designs für die Schnittstelle und die Klasse vor dem Codieren erstellt. Richtig?

    
Tundey 13.03.2009 17:57
quelle
0

Im Allgemeinen brauchen Sie keine Schnittstelle, es sei denn, Sie haben mehrere Klassen im Auge, die es implementieren werden. Also, die Schnittstelle würde zuerst kommen.

    
Yes - that Jake. 13.03.2009 17:59
quelle
0

Ich würde S. Lott zustimmen müssen und hinzufügen, dass das Design eines Interfaces "in Stein gemeißelt" ist, sobald Sie es erstellt haben.

Aus diesem Grund sollte ein Interface erst erstellt werden, wenn Sie alles wissen, das es enthält.

    
Powerlord 13.03.2009 18:06
quelle
0

Die Klasse sollte zuerst kommen.

Ein schönes Design kann nur bestimmt werden, um schön zu sein, wenn es dem Tiegel der Veränderung unterzogen wird. Woher wissen Sie, ob Ihre Schnittstellen dem Test der Zeit standhalten, wenn sie nicht von Anfang an durch Code gefälscht wurden?

    
hyuan 13.03.2009 20:09
quelle
0

Ich möchte zwei verschiedene Ansichten darüber, welche Schnittstellen sind:

  1. Eine Schnittstelle ist eine Abstraktion einer wichtigen Entität in Ihrem System. Sie können Ihr System basierend auf Schnittstellen und den Kollaborationen zwischen ihnen entwerfen.
  2. Eine Schnittstelle ist ein Platz im System, an dem Sie die Implementierung variieren können. Plattformunterschiede, Bibliotheken von Drittanbietern usw. sind durch eine Schnittstelle verborgen, die für verschiedene Konfigurationen Ihrer Software unterschiedlich implementiert werden kann.

In beiden Fällen entwerfen Sie jedoch zuerst und dann programmieren Sie.

Für ein neues System würde ich erwarten, dass zuerst Kandidatenschnittstellen identifiziert werden, die später von Klassen implementiert werden. Für ein vorhandenes System wird eine Schnittstelle zu vorhandenen Klassen entwickelt, wenn Sie in Ihrem System eine wichtige Entität oder einen Variationspunkt entdecken, an dem es zuvor nicht so wichtig war oder an dem Sie zuvor keinen Variationspunkt angeben mussten.

    
andreas buykx 16.03.2009 09:00
quelle
0

Was kommt zuerst? Die Notwendigkeit für ein Feature oder die Implementierung eines Features?

In meinem eigenen Workflow kommt das Interface zuerst spontan. Wenn ein Teil meines Projekts ein neues Feature benötigt, ist es so aufgebaut, wie ich es verwenden möchte, d. H. Seine Schnittstelle. Dann folgt die Implementierung.

Auf diese Weise enthält die Implementierung nur das, was tatsächlich benötigt wird, und es wird keine Zeit damit verschwendet, ein glänzend nutzloses Stück Code zu überarbeiten.

    
mouviciel 16.03.2009 09:20
quelle
0

Schnittstellen entwickeln sich im Laufe der Zeit sehr schlecht. Wann immer Sie die Schnittstelle ändern, brechen Sie den Vertrag. Alle Klassen, die die Schnittstelle implementieren, müssen refaktoriert werden. Um rückwärtskompatibel zu bleiben, werden Entwickler kreativ und gestalten IFoo2 über IFoo. Dies wird mit der Zeit zu einem Alptraum.

Beachten Sie Folgendes: Definieren Sie lieber Klassen über Schnittstellen. Verwenden Sie Schnittstellen, wenn Sie eine polymorphe Hierarchie von Werttypen bereitstellen möchten. Eine andere Art der Verwendung von Schnittstellen besteht darin, einen ähnlichen Effekt wie bei der Mehrfachvererbung zu erzielen.

    
Patrick Peters 20.03.2009 11:36
quelle
-1

Ich weiß nicht, welches das Beste ist, aber ich bin mir sicher, dass die richtige Antwort immer eine dieser beiden Optionen in allen Kontexten ist!

    
Ken 13.03.2009 20:22
quelle

Tags und Links