2016-05-12 5 views
-2

Beim Erstellen einer benutzerdefinierten 3D-Klasse Point mit Koordinatenwerten mit einfacher Genauigkeit in C# musste ich eine Methode schreiben, um den Abstand zwischen zwei Punkten zu berechnen. Dann dachte ich über die A -> B Graphnotation, die "von A nach B" bedeutet, und überlegte, den > Operator zu überladen, da es keinen Sinn hat, über einen Punkt A zu denken, der "größer" ist als ein Punkt B (außerdem kann der Operator -> nicht überlastet sein).Kann verschleierter Code manchmal nützlich sein?

Also hat ich die folgenden Methoden:

/// <summary> 
/// Calculates the Manhattan distance between the two points. 
/// </summary> 
public static float operator>(Point p1, Point p2) 
{ 
    return Math.Abs(p1.X - p2.X) + 
      Math.Abs(p1.Y - p2.Y) + 
      Math.Abs(p1.Z - p2.Z); 
} 

/// <summary> 
/// Calculates the euclidean distance between the two points. 
/// </summary> 
public static double operator>=(Point p1, Point p2) 
{ 
    return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + 
        Math.Pow(p1.Y - p2.Y, 2) + 
        Math.Pow(p1.Z - p2.Z, 2)); 
} 

Dies führt zu Code wie folgt:

var manhattan = A > B; 
var euclidean = A >= B; 

Der Code scheint verschleiert zu werden, aber wenn man den Griff davon bekommt, ist es durchaus einfach zu lesen und kürzer als mit A.DistanceTo(B).

Die Frage ist, sollte ich diese Art von Code vollständig vermeiden? Wenn ja, aus welchem ​​Grund? Ich bin ziemlich besorgt mit Clean Code, und ich bin mir nicht sicher, ob das sauber oder nicht sein könnte. Wenn Sie denken, dass ein solcher Code manchmal erlaubt ist, könnten Sie Beispiele bereitstellen?

+0

In diesem speziellen Fall, ja, weil der '> =' Operator fast allgemein als "größer als oder gleich" bekannt ist, und Sie das hier stark untergraben. Die meisten Leute würden sich diesen Operator anschauen und denken: "Warum sagt es mir nicht, ob" A "größer ist als" B "?" – casperOne

+3

In 6 Monaten werden Sie Ihren Code beibehalten und sich fragen, warum Sie überprüfen, ob A größer als B ist. Ist es so schlimm, stattdessen eine 'DistanceTo'-Methode zu verwenden? Das erklärt mir klarer, was Sie tun. – Default

+0

Vielleicht können Sie einen anderen Operator nehmen, der mit Klassen keinen Sinn macht, wie >> (Bitverschiebung) – Gusman

Antwort

3

Im Allgemeinen sollten Sie diese Art von Code vermeiden (außer es ist Teil einer tieferen DSL).

Das Überschreiben allgemeiner Operatoren und Methoden mit unerwartetem Verhalten macht es sehr schwierig, den Code zu erfassen, zu verstehen und zu debuggen.

Stellen Sie sich vor, Sie lesen ein Buch, und obwohl die Wörter wie Englisch aussehen, hat der Autor die Bedeutung einiger Schlüsselwörter geändert, indem Sie einige Notizen in einem Anhang auf der Rückseite machen, so dass Sie ständig hin und her blättern jeder Satz bedeutet, was Sie denken, dass es tut.

Der Code sollte so geschrieben sein, dass er von Menschen gelesen werden kann. Je leichter Sie diese Aufgabe erledigen und je weniger Überraschungen Sie eingehen, desto besser wird es sein.

+0

migriert werden sollte. Ich verstehe Ihre Antwort vollständig, aber wie erklären Sie dann funktionale Programmiersprachen wie F #? Code in diesen Sprachen ist alles andere als lesbar, aber sie erhöhen ihre Popularität. – Charlie

+0

Auch im Spiel (3D-Programme, Sie bekommen mich;)) Mathe ist sehr häufig, um Operatoren zu ersetzen, zum Beispiel eine sehr übliche Änderung ist die Änderung der "*" -Operator auf das Skalarprodukt für Vektoren. – Gusman

+0

Ich würde argumentieren, dass die Lesbarkeit von funktionalen Sprachen nur eine Frage der Vertrautheit ist. Funktionale Sprachen können sehr gut lesbar (und prägnant!) Sein. Der wichtige Teil ist, wenn ich F # lerne, sollte ich es im kanonischen Stil schreiben, so dass es für jemanden anderen leicht ist, der weiß, dass F # es liest. – Paolo

Verwandte Themen