2009-04-01 16 views
1

Wenn Sie unveränderliche Klassen entwerfen, bevorzugen Sie:Konventionen für unveränderliche Objekte

Layer.ColorCorrect (layer) 

oder

layer.ColorCorrect () 

Für mich # 1 intuitiver scheint, statt # 2, die aussieht wie es ändert das Objekt, das referenziert wird, da es eine Instanzmethode ist, könnte es auch die Interna ändern, richtig?

Antwort

8

Ich würde bevorzugen, eine Instanzmethode zu verwenden, aber wählen Sie den Namen, um die Tatsache widerzuspiegeln, dass es die vorhandene Instanz nicht ändert. Zum Beispiel:

layer.AfterColorCorrection() 

oder

layer.WithCorrectedColors() 

statische Methoden verwenden wird ziemlich schnell ermüdend. Auch wenn Sie Ihren Benutzern klar machen, dass der Typ unveränderlich ist, sollten sie sich ziemlich schnell zurechtfinden. Jeder wird von String.Replace gestolpert, die nichts im Ziel tatsächlich ersetzen - aber sie machen nicht den gleichen Fehler. Mit besseren Namen sowie sollte es dir gut gehen.

Ich fragte eine related question über "Hinzufügen" zu einer unveränderlichen Liste - die beste Lösung dort IMO ist "Plus" statt "Add" zu verwenden; wieder bedeutet dies nicht, dass der ursprüngliche Wert geändert wird. Vielleicht finden Sie andere Antworten auf diese Frage nützlich.

+0

Danke Jon. Ihre Frage ist sehr hilfreich. Sieht so aus, als ob Sie auch über die bestmöglichen Praktiken besorgt sind :) –

+0

Ich denke gerne über Best Practices nach. Sie müssen meine Kollegen fragen, inwieweit mein Produktionscode sie wiedergibt ... –

+0

lol. Persönlich versuche ich, das zu verwenden, was ich so schnell wie möglich lerne, damit ich nicht vergesse, sie in meine Arbeit zu integrieren :) Nur aus Neugier, verwenden Sie C# für die meisten Dinge, die Sie bei der Arbeit tun? –

1

Normalerweise würde Sie so etwas wie:

layer = layer.ColorCorrect([required parameters here]); 

Dies wäre ähnlich zu

mystring = mystring.Substring(1, 2); 

Wenn eine neue Zeichenfolge erstellt, die die Teil des ersten ist.

+0

Danke, du meinst Params wie in Params Keyword, andere Werte zu übergeben? –

+0

Nein, nur als Platzhalter, um anzuzeigen, dass Parameter vorhanden sein können. –

0

Es ist absolut gegen OOPS Prinzipien, statische Methode zu schreiben, eine Instanz übergeben und es fast wie prozedurale Programmierung wie "C" aussehen. Auch in der ersten Methode geben Sie Layer zweimal ein, was es für den Leser mehrdeutig macht.

+0

Danke. Was ist OOPS? Kannst du mir bitte sagen, warum es nicht gut ist? Auch die Layer-Var war nur ein Beispiel. Was wäre, wenn es etwas wie normalMap wäre und dann an Layer.ColorCorrect übergeben würde, was dem Programmierer sagen würde, dass es sich um eine Ebene handelt. –

+0

OOPS bedeutet objektorientiertes Programmiersystem. Wenn Klassenmitglieder geändert werden müssen, erstellen Sie normalerweise Eigenschaften, indem Sie Accessoren und Mutatoren erstellen. Die meisten Funktionen können niemals etwas modifizieren, aber sie sind immer noch als Instanzmethoden codiert. –

0

Die Verwendung der statischen Methode verhindert die Vererbung, nicht wahr? Das scheint eine ziemlich signifikante Einschränkung zu sein.

5

Meine persönliche Präferenz ist es, darauf zu achten, dass der Typ unveränderlich ist. Zum Beispiel würde ich es ImmutableLayer vs. Layer nennen. Oder wenn aus irgendeinem Grund Immutable kein gutes Wort ist, um den Namen voranzutreiben, werde ich der Klasse ein Attribut hinzufügen, das anzeigt, dass es unveränderlich ist (Attribut wird in beiden Fällen hinzugefügt).

Das hat es Höhen und Tiefen. Das ist, gibt es einen zentralen Ort, um auf Unverfälschbarkeit zu überprüfen. Werfen Sie einen Blick auf den Typ und Sie sind im Geschäft. Sie müssen keine neuen Methodennamen oder Konventionen lernen. Der Nachteil des Ansatzes besteht darin, dass Sie in bestimmten Typ-Inferenz-Szenarien nicht erkennen können, dass der Wert unveränderlich ist. Zum Beispiel funktioniert dieser Code genauso gut für eine ImmutableCollection und eine normale Liste

var col = GetTheCollection(); 
col.Add(42); 

Allerdings Ich mag zu Unveränderlichkeit accomidate keine Methodennamen zu ändern. Der Grund dafür ist, dass es sich um ein Problem handelt, das Sie immer wieder lösen müssen. Dinge benennen sollte einfach sein, aber es ist manchmal unglaublich schwierig.Denken Sie an all die Arten, die Sie jemals unveränderlich machen wollten. Stellen Sie sich vor, Sie müssten für jede Mutationsmethode dieser Typen neue Namen oder Konventionen finden. Es ist eine nicht-triviale Aufgabe und Sie werden viel Zeit damit verbringen, Benutzer über diese neuen Konventionen zu informieren.

Mein Traum-Szenario ist jedoch, einen Weg zu finden, um die Sichtbarkeit von unveränderlichen Typen zu erhöhen. Weil das das eigentliche Problem ist, ist es nicht unveränderlich, den Typ zu kennen. Derzeit gibt es keinen guten Weg, dies für alle Szenarien zu tun, aber ich hoffe auf die nächste Version der Sprachen/IDE.

3

@JaredPar hat die beste Antwort, IMO, aber keine der Antworten ist großartig, weil es heute keine "großartigen" Lösungen dafür gibt. Wir brauchen bessere Werkzeuge und Designrichtlinien, die sich im Einklang mit den Werkzeugen entwickeln, um besser mit der steigenden Popularität unveränderlicher Objekte umgehen zu können.

@ JonSkeet Antwort funktioniert gut in einem API-Kontext, wo fast alles veränderbar ist, aber es fällt als unveränderliche Objekte zur Norm werden (wie alle Methoden lange schreckliche Namen haben).

Der "beste" Name hängt vom Code-Kontext ab, von dem Sie umgeben sind. Die einzige Strategie, von der ich denke, dass sie über das Spektrum der "meist veränderbaren" bis "weitgehend unveränderlichen" Kontexte reicht, ist diejenige, die Jared erwähnt, wo das Werkzeug es offensichtlich macht, ob ein bestimmtes Objekt unveränderlich ist und dann jede Methode den Imperativ hat. name (egoAdd), der entweder das Empfängerobjekt (wenn es veränderlich ist) oder das neue Objekt (wenn es unveränderlich ist) zurückgibt.

(Leider: "fließende" effektvolle APIs wie "StringBuilder" bedeuten, dass man nicht nur die Methodensignatur betrachten kann, um zu entscheiden, ob das Empfängerobjekt unveränderlich ist, Geben Sie die gleiche Unterschrift wie "eine Kopie zurückgeben."

Verwandte Themen