Wenn ein Team / Unternehmen ein Framework / Compiler / Tool-Set ausliefert, verfügt es bereits über einige Erfahrungen und Best Practices. Sie teilen es als Richtlinien. Richtlinien sind Empfehlungen . Wenn Sie keine mögen, können Sie sie ignorieren. Der Compiler kompiliert weiterhin Ihren Code. Aber wenn in Rom ...
Dies ist meine Vision, warum das TypeScript-Team empfiehlt, I
Schnittstellen nicht zu fixieren.
Das Hauptargument von I
Unterstützern von -prefix-for-interface ist, dass das Präfix hilfreich ist, um sofort zu prüfen, ob der Typ eine Schnittstelle ist. Die Aussage, dass das Präfix hilfreich ist, um sofort zu grokken (spähen), ist ein Appell an die ungarische Notation . I
Präfix für Schnittstellenname, C
Klasse, A
abstrakte Klasse, s
Zeichenfolgenvariable, c
Konstantenvariable, i
Ganzzahlvariable. Ich bin damit einverstanden, dass eine solche Namensdekoration Ihnen Typinformationen liefern kann, ohne mit der Maus über die Kennung zu fahren oder über einen Hotkey zur Typdefinition zu navigieren. Dieser winzige Vorteil wird durch die nachstehend genannten ungarischen Notationsnachteile und andere Gründe aufgewogen. Die ungarische Notation wird in zeitgenössischen Rahmenbedingungen nicht verwendet. C # hatI
Präfix (und dies ist das einzige Präfix in C #) für Schnittstellen aus historischen Gründen (COM). Rückblickend ist einer der .NET-Architekten (Brad Abrams) der Meinung, dass es besser gewesen wäre, kein I
Präfix zu verwenden . TypeScript ist COM-Legacy-frei, daher gibt es keine I
Präfix-für-Schnittstelle-Regel.
Grund # 2- I
Präfix verstößt gegen das Kapselungsprinzip
Nehmen wir an, Sie bekommen eine Blackbox. Sie erhalten eine Typreferenz, mit der Sie mit diesem Feld interagieren können. Es sollte Ihnen egal sein, ob es sich um eine Schnittstelle oder eine Klasse handelt. Sie verwenden nur den Schnittstellenteil. Die Forderung zu wissen, was es ist (Schnittstelle, spezifische Implementierung oder abstrakte Klasse), ist eine Verletzung der Kapselung.
Beispiel: Nehmen wir an, Sie müssen API Design Mythos: Schnittstelle als Vertrag in Ihrem Code korrigieren, z. B. ICar
Schnittstelle löschen und Car
stattdessen Basisklasse verwenden. Dann müssen Sie einen solchen Austausch bei allen Verbrauchern durchführen. I
-prefix führt zu einer impliziten Abhängigkeit der Verbraucher von Black-Box-Implementierungsdetails.
Grund Nr. 3 Schutz vor schlechten Namen
Entwickler sind faul, über Namen richtig nachzudenken. Das Benennen ist eines der beiden schwierigen Dinge in der Informatik . Wenn ein Entwickler eine Schnittstelle extrahieren muss, ist es einfach, den Buchstaben I
zum Klassennamen hinzuzufügen, und Sie erhalten einen Schnittstellennamen. Wenn Sie das I
Präfix für Schnittstellen nicht zulassen , müssen Entwickler ihr Gehirn belasten, um geeignete Namen für Schnittstellen auszuwählen. Ausgewählte Namen sollten sich nicht nur im Präfix unterscheiden, sondern auch den Unterschied zwischen den Absichten betonen.
Abstraction Fall: Sie sollten nicht keine definieren ICar
Schnittstelle und eine zugehörige Car
Klasse. Car
ist eine Abstraktion und sollte für den Vertrag verwendet werden. Implementierungen sollten beschreibende, eindeutige Namen haben, z SportsCar, SuvCar, HollowCar
.
Gutes Beispiel: WpfeServerAutosuggestManager implements AutosuggestManager
, FileBasedAutosuggestManager implements AutosuggestManager
.
Schlechtes Beispiel : AutosuggestManager implements IAutosuggestManager
.
In meiner Praxis habe ich viele Leute getroffen, die gedankenlos einen Schnittstellenteil einer Klasse in einer separaten Schnittstelle mit Car implements ICar
Namensschema dupliziert haben . Das Duplizieren eines Schnittstellenteils einer Klasse in einem separaten Schnittstellentyp konvertiert sie nicht auf magische Weise in eine Abstraktion. Sie erhalten weiterhin eine konkrete Implementierung, jedoch mit einem doppelten Schnittstellenteil. Wenn Ihre Abstraktion nicht so gut ist, wird sie durch das Duplizieren des Schnittstellenteils ohnehin nicht verbessert. Abstraktion zu extrahieren ist harte Arbeit.
HINWEIS: In TS benötigen Sie keine separate Schnittstelle zum Verspotten von Klassen oder zum Überladen von Funktionen. Anstatt eine separate Schnittstelle zu erstellen, die öffentliche Mitglieder einer Klasse beschreibt, können Sie TypeScript-Dienstprogrammtypen verwenden . Required<T>
Konstruiert zB einen Typ, der aus allen öffentlichen Mitgliedern des Typs besteht T
.
export class SecurityPrincipalStub implements Required<SecurityPrincipal> {
public isFeatureEnabled(entitlement: Entitlement): boolean {
return true;
}
public isWidgetEnabled(kind: string): boolean {
return true;
}
public areAdminToolsEnabled(): boolean {
return true;
}
}
Wenn Sie einen Typ ohne einige öffentliche Mitglieder erstellen möchten, können Sie die Kombination aus Auslassen und Ausschließen verwenden .
I
Präfixes für Sie und Ihr Team sinnvoll ist, verwenden Sie es. Wenn nicht, vielleicht den Java-Stil vonSomeThing
(Schnittstelle) mitSomeThingImpl
(Implementierung), dann verwenden Sie das auf jeden Fall.