Beim Durchsuchen von Code, den ich geschrieben habe, bin ich auf das folgende Konstrukt gestoßen, das mich zum Nachdenken gebracht hat. Auf den ersten Blick scheint es sauber genug zu sein. Ja, im eigentlichen Code hat die getLocation()
Methode einen etwas spezifischeren Namen, der genauer beschreibt, welchen Ort sie erhält.
service.setLocation(this.configuration.getLocation().toString());
In diesem Fall service
handelt es sich um eine Instanzvariable eines bekannten Typs, die innerhalb der Methode deklariert wurde. this.configuration
wird an den Klassenkonstruktor übergeben und ist eine Instanz einer Klasse, die eine bestimmte Schnittstelle implementiert (die eine öffentliche getLocation()
Methode erfordert). Daher ist der Rückgabetyp des Ausdrucks this.configuration.getLocation()
bekannt. speziell in diesem Fall ist es ein java.net.URL
, während ein service.setLocation()
will String
. Da die beiden Typen String und URL nicht direkt kompatibel sind, einige ist eine Art Umwandlung erforderlich , um den quadratischen Pflock in dem runden Loch zu passen.
Jedoch , nach dem Gesetz von Demeter , wie in der zitierten Clean Code , ein Verfahren f in der Klasse C sollten nur Methoden aufrufen C , Objekte erstellt von oder als Argumente zu übergeben f , und Objekte in Instanzvariablen gehalten C . Alles darüber hinausgehende (das letzte toString()
in meinem speziellen obigen Fall, es sei denn, Sie betrachten ein temporäres Objekt, das als Ergebnis des Methodenaufrufs selbst erstellt wurde; in diesem Fall scheint das gesamte Gesetz streitig zu sein), ist unzulässig.
Gibt es einen stichhaltigen Grund, warum ein Anruf wie der oben genannte angesichts der aufgeführten Einschränkungen abgelehnt oder sogar abgelehnt werden sollte? Oder bin ich nur zu pingelig?
Wenn ich eine Methode implementieren würde, URLToString()
die einfach toString()
ein URL
Objekt (wie das von zurückgegebene getLocation()
) aufruft , das als Parameter übergeben wurde, und das Ergebnis zurückgibt, könnte ich den getLocation()
Aufruf darin einschließen, um genau dasselbe Ergebnis zu erzielen. effektiv würde ich die umwandlung nur einen schritt nach außen verschieben. Wäre das irgendwie akzeptabel? (Es scheint mir intuitiv, dass es in keiner Weise einen Unterschied machen sollte, da sich die Dinge nur ein wenig bewegen. Nach dem zitierten Wortlaut des Gesetzes von Demeter wäre es jedoch akzeptabel, da ich würde dann direkt an einem Parameter zu einer Funktion arbeiten.)
Würde es einen Unterschied machen, wenn es sich um etwas Exotischeres handeln würde, als toString()
einen Standardtyp anzurufen?
Denken Sie bei der Beantwortung daran, dass service
es nicht praktikabel ist , das Verhalten oder die API des Typs zu ändern, von dem die Variable ist. Nehmen wir aus Gründen der Argumentation an, dass das Ändern des Rückgabetyps von getLocation()
ebenfalls unpraktisch ist.