Benennung der Schnittstelle: Präfix 'Can-' vs Suffix '-Able'


29

Es ist üblich, '-able' als Suffix für Schnittstellen zu verwenden, z

Serializable Printable Enumerable Drinkable Shootable Drehbar

Ich dachte, dass "Can-" besser sein könnte, weil es aussagekräftiger sein könnte. Ja, es ist wortreicher und fügt dem Schnittstellennamen Rauschen hinzu. Insbesondere können passive Verben verwendet werden.

ZB 1 bedeutet Shootable, dass das Objekt schießen kann (eine Waffe könnte dies implementieren), oder bedeutet es, dass auf es geschossen werden kann (eine Zieltafel könnte dies implementieren). Mit dem Präfix "Can-" wäre ersteres "CanShoot" und letzteres "CanBeShotAt" oder "CanShootAt".

ZB 2 Ein Dokument 'CanBePrinted' und ein Drucker 'CanPrint'

Oder sollten wir uns an '-Able' halten und die Dokumentation den Kontext bereitstellen lassen?

Irgendwelche Meinungen.


Mann, benutze "-able". Zeitraum.
Tulains Córdova

2
Verwenden Sie beide fürclass Cannibal implements Can, Able {}
Thomas Eding

Antworten:


18

Vielleicht willst du es können?

Einige Beispiele aus .Net:

NetworkStream.Readable
NetworkStream.Writable
Stream.CanRead
Stream.CanWrite
Type.IsSerializable

Es scheint keinen einheitlichen Standard zu geben. Gehen Sie mit dem, was gut liest.

if (document.IsPrintable && printer.CanPrint) { printer.Print(document) }

EDIT: Wie bereits erwähnt, ging es um Schnittstellen, nicht um Eigenschaften.

In diesem Fall kann ich keine Schnittstellen mit dem Namen Can- finden. Schnittstellen sind in der Regel immer verwendbar. Ich würde dieser Terminologie zustimmen. Eine Methode kann als Parameter ein ISerializable objectoder anfordern IPrintable document. Nach einem ICanBeSerialized objectoder einem zu fragen ICanBePrinted documentist sehr umständlich zu lesen.

Auf der anderen Seite, dem Drucker, würde ich vorschlagen, einfach die Schnittstelle aufzurufen IPrinter. Ihre Methode wird nach a fragen IPrinter device.

Lesen Sie die Methodensignatur unten laut vor. (Persönlich halte ich das Präfix "I" für stumm.) Liest es gut? Klingt es richtig?

void PrintDocument(IPrinter device, IPrintable document)
{
    device.Print(document)
}

2
Document.IsPrintable ist besser als Document.CanBePrinted. Soweit ich das beurteilen kann, haben sie -able verwendet, um Passiv zu vermeiden.
Thanos Papathanasiou

"Kann gedruckt werden" scheint besser zu sein als "ist druckbar".
Danny Varod

1
"Passive Stimme wird verwendet, wenn der Fokus auf der Aktion liegt. Es ist jedoch nicht wichtig oder nicht bekannt, wer oder was die Aktion ausführt." Ich kann nur vermuten, dass sie wollten, dass der Fokus auf dem Objekt und nicht auf der Handlung bleibt. Wenn also "Type.IsSerializable" eine Ausnahme auslöst, ist dies der Fehler des Typs. nicht die Methoden, aber wenn ein "Type.CanBeSerialized" eine Ausnahme auslöst, würden Sie die Methode und nicht den Typ beschuldigen. Zwar ist der Unterschied gering, aber es ist da.
Thanos Papathanasiou

3
Ich sehe, dass dies die akzeptierte Antwort ist, aber dies beantwortet nicht die Frage des OP. Die angegebenen Beispiele sind Eigenschaftsnamen . Die OP bittet um eine Namenskonvention für Interface - Namen, wie ISerializable, IDataErrorInfo, und INotifyPropertyChanged.
Kevin McCormick

@ KevinMcCormick, guter Punkt! Bearbeitungen oben.
Hand-E-Food am

23

Grammatisch gesehen ist "canFoobar" ein Prädikat, während "Foobarable" ein Adjektiv oder ein Substantiv ist (normalerweise ein Substantiv im Kontext einer API).

Beachten Sie auch den subtilen Unterschied: -able impliziert eine passive Rolle für das Nomen, auf das es angewendet wird. can- impliziert eine aktive Rolle, das heißt, wenn Something canFoobar ist, kann es etwas anderes bewirken. Oder aus einem anderen Blickwinkel: Wenn A B kann, dann A.canFoobar()und B is Foobarable.

In Bezug auf die OOP-Expressivität würde ich Prädikate mit Methoden oder Eigenschaften verknüpfen, während Substantive Klassen oder Schnittstellen sind. So:

instance.canFoobar();

class Something implements Foobarable { ... }

7

Persönlich würde ich mich an die -able-Version halten. Hier ist mein Grund: Die meisten (alle?) Grafischen Editoren schlagen Kennungen basierend auf Ihren Eingaben vor. Obwohl einige von ihnen "intelligent" genug sind, um auch innerhalb von Bezeichnern zu suchen, bieten einige nur Suchanfänge von Bezeichnern an.

Um die Eingabe zu beschleunigen, möchten Sie die Liste der vorgeschlagenen Bezeichner mit möglichst wenigen Tastenanschlägen kürzen. Je mehr Bezeichner den gleichen Anfang haben, zB 'ICan-', desto mehr Zeichen müssen Sie eingeben.

Wenn Sie der Meinung sind, dass dies in Ihrem Fall kein Problem ist, ist dies großartig und ich würde empfehlen, andere Kriterien zu verwenden, um eine Namenskonvention zu wählen. In einigen Fällen, z. B. in unserem Team, bevorzugen wir Bezeichner, die sich nach möglichst wenigen Tastenanschlägen unterscheiden.

Abgesehen davon würde ich empfehlen, die Namenskonvention zu verwenden, die Ihren Code für diejenigen, die an dem Projekt arbeiten, am verständlichsten macht. Führen Sie ein Gespräch in Ihrem Team. Es gibt kein Richtig oder Falsch als solches. Nur Konventionen, die funktionieren und Konventionen, die weniger funktionieren.

Vergessen Sie nicht, dass Sie mit guten Refactoring-Tools die Dinge so oft umbenennen können, wie Sie möchten. Es ist also einfach, mit verschiedenen Ansätzen zu experimentieren.


1
+1. Meine Argumentation wäre die gleiche: Setzen Sie das steuernde Verb an die erste Stelle, um das Suchen / Finden / Sortieren in der IDE zu vereinfachen.
Pap

1
So funktioniert nicht nur Intellisense, sondern auch das Scannen von Text durch den Menschen. Präfixe machen Ihren Code weniger lesbar
jk.

7

Es ist klar, dass Präfix und Suffix für verschiedene Arten von Aktionen bzw. verschiedene Richtungen einer Aktion fast offensichtlich sind .

Die aktuelle Verwendung und die aktuellen Einstellungen können jedoch aus vielen Gründen inkonsistent sein.

Die Aktion wird von dem Objekt ausgeführt:
CanShoot -> Es schießt (auf) etwas
CanFly -> Es fliegt
CanChange -> Es ändert sich

Die Aktion wird für das Objekt ausgeführt:
Lesbar -> Sie können es lesen.
Beschreibbar -> Sie können es schreiben (in das Objekt schreiben).
Druckbar -> Sie können es drucken

Auch wenn dies möglicherweise keine Regel oder sogar nur logisch ist, hilft es, die Konvention zu übernehmen und die Verwendungskonsistenz bei der Benennung von Variablen beizubehalten.


4

Ich denke, Sie möchten vielleicht zwischen Fähigkeit und Erlaubnis unterscheiden. Während Serializableund CanSerializeimplizieren, dass etwas serialisiert werden kann, gibt es auch Berechtigungsprobleme (oder möglicherweise einen Mangel an Speicherplatz) und Sie müssen dies möglicherweise berücksichtigen MaySerialize. Das Belassen von Dingen auf ~ablebeseitigt die Notwendigkeit, zwischen canund zu unterscheiden may.


SerializableIfNotDiskFullAndIfNotPermissionMissing ... Lol :)
Max

2

Wenn ich Interfaces in Unterklassen einordne / implementiere, denke ich, ist die Faustregel, dass man sagen kann, dass "B ein A ist" (wobei B A implementiert). Es klingt nicht richtig zu sagen:

A Documentist aCanBePrinted

Aber es klingt richtig (oder zumindest besser) zu sagen:

A Documentist aPrintable


2

Ich denke, dass sowohl grammatikalisch als auch konventionell Xable für Namen von Schnittstellen besser ist, während IsX, CanX, DoesX für Namen von Eigenschaften besser sind.

Von MSDN:

"Benennen Sie Boolesche Eigenschaften mit einem positiven Ausdruck (CanSeek anstelle von CantSeek). Optional können Sie Booleschen Eigenschaften auch Is, Can oder Has voranstellen, jedoch nur dort, wo dies einen Mehrwert bietet." http://msdn.microsoft.com/en-us/library/ms229012.aspx


+1 für den hilfreichen Link; Ich kann nie herausfinden, was ich benennen soll
CamelBlues

0

Meiner Meinung nach ist die "-able" -Variante viel lesbarer als das von Ihnen vorgeschlagene "CanDoSomething", das viel mehr Kamelbuckel verursacht.


1
und Can- ist eher ein Methodenname
Ratschenfreak

Eigenschaftsname - siehe MSDN. Ein Methodenname sollte "Verben oder Verbalphrasen" sein. Außerdem, was ist los mit mehreren Buckeln?
Danny Varod

0

Wird in Scala *Ablefür Schnittstellen verwendet, Can*wird jedoch für das Typklassenmuster verwendet. Um bestimmte Methoden aufrufen zu können, muss im Gültigkeitsbereich im Wesentlichen ein impliziter Wert eines bestimmten Typs vorhanden sein. Dem Namen dieses Typs wird manchmal ein Präfix vorangestellt Can.


Can * ist kein guter Name für eine Klasse. Zitat aus MSDN: "Benennen Sie Klassen, Schnittstellen und Werttypen mit Substantiven, Nominalphrasen oder gelegentlich Adjektivphrasen in Pascal- Schreibweise ", Link: msdn.microsoft.com/en-us/library/ms229040.aspx Guter Name für Klasse wäre Dokument, akzeptabler Name wäre Druckbar.
Danny Varod

Ein Beispiel in der Scala-Sprache ist das CanBuildFrom. Dies wäre ein Adjektivsatz. Der Anwendungsfall dieser Klasse unterscheidet sich stark von dem anderer Klassen. Instanzen dieser Klasse werden vom Client so gut wie nie konstruiert oder aufgelöst, sondern sind für bestimmte Typen im Geltungsbereich verfügbar. Wenn sie für einen bestimmten Typ verfügbar sind, können Methoden mit diesem Typ aufgerufen werden, für die diese Typklasse erforderlich ist. Dies dient dazu, einen Erweiterungsmechanismus anzubieten, der flexibler ist als die Untertypisierung. Siehe scala-lang.org/node/114 .
Axel22

Ich erinnere mich nur an die Verwendung von Adjektivphrasen für Scheinklassen, die Schnittstellen für Unit-Tests implementieren - da sie keine wirkliche Rolle spielten.
Danny Varod
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.