Kann eine Schnittstelle irgendwie Lambda-Ausdruck-Implementierungen verhindern?

8

Hintergrund

Ich gebe die folgende Schnittstelle als Teil einer API frei:

%Vor%

Der Kunde übergibt mir Modelle von "Weiden" als Objekte, die diese Schnittstelle implementieren. Jedes Objekt repräsentiert eine Weide.

Auf meiner Seite der API verfolge ich zu verschiedenen Zeiten "Besuche" dieser Objekte und rufe pasture.yield(time, lastVisitTime) dann auf, wenn ich wissen muss, wie viel die Weide in der Zwischenzeit produziert hätte.

Das Problem besteht darin, dass diese Schnittstelle auf der Client-Seite als Lambda-Ausdruck implementiert werden kann, und anscheinend erzeugt jede Lambda-Ausdruckinstanziierung nicht unbedingt ein neues Objekt mit einer neuen Identität , auf das ich mich verlasse, um zu verfolgen, welche Weiden zu welchen Zeiten besucht wurden.

Frage

Gibt es eine Möglichkeit zu verhindern, dass die Schnittstelle als Lambda-Ausdruck implementiert wird, sondern stattdessen vom Client als anonyme Klasse implementiert wird. Eine Dummy-Methode hinzuzufügen, würde natürlich ausreichen, aber das wäre meiner Meinung nach willkürlich und unordentlich. Gibt es einen anderen Weg?

    
Museful 18.08.2015, 08:27
quelle

3 Antworten

5

Es ist nicht der Lambda-Kanten-Fall, der Ihr Problem ist.

Sie machen eine Annahme , dass dasselbe Objekt die gleiche Pasture darstellt und Ihr Objekt daher zwei Dinge auf einmal macht. Das ist ein Code-Geruch und ist der Grund für Ihre Schwierigkeiten.

Sie sollten Ihre Pasture -Objekte zwingen, etwas wie equals zu implementieren, damit Sie dann prüfen können, ob die Elemente identisch sind. Leider gibt es keine interface , die das tut, die nächste ist Comparable .

%Vor%     
OldCurmudgeon 18.08.2015, 08:55
quelle
1

Sie können der Methode eine geprüfte Ausnahme hinzufügen:

%Vor%

Aber es ist seltsam, lambda zu leugnen.

    
sibnick 18.08.2015 10:53
quelle
0
  

"[...] anscheinend erzeugt jede Lambda-Ausdrucksinstanziierung nicht unbedingt ein neues Objekt mit einer neuen Identität, worauf ich mich verlasse, um zu verfolgen, welche Weiden zu welchen Zeiten besucht wurden. "

( Hervorhebung meins.)

Wenn Sie etwas tun und es Ihnen Probleme bereitet, warum hören Sie nicht einfach damit auf?

Stattdessen, wenn ein Kunde Ihnen eine "Weide" übergibt, weisen Sie ihm eine neue interne ID zu und ordnen Sie die Weide (und alle Metadaten, wie die letzte Besuchszeit, die Sie wünschen) zu speichern Sie es) mit der ID.

Auf diese Weise ist es egal wenn der Kunde Ihnen das gleiche Weideobjekt mehrmals übergibt - was Ihren Code betrifft, werden diese Weiden unterschiedliche IDs haben und daher unterschiedliche Weiden darstellen mit ihren eigenen letzten Besuchszeiten und anderen Daten, selbst wenn die clientseitigen Teile von ihnen durch das gleiche Objekt implementiert werden könnten.

(Dies gilt zumindest so lange, wie die wiederverwendeten Weideobjekte keinen veränderlichen internen Zustand beibehalten; Ihr Client sollte jedoch besser wissen, Objekte mit diesem Status wiederzuverwenden und so funktioniert die Java-8-lambda-Implementierung .)

Hier eine kurze Beispielimplementierung mit einfachen sequentiellen Ganzzahl-IDs:

%Vor%

Das Schlüsselmerkmal hier ist, dass Sie nie Pasture Objekte weitergeben, nachdem sie hinzugefügt wurden und ihnen eine ID zugewiesen wurde, und Sie vor allem sie nicht vergleichen oder als Map-Schlüssel verwenden. Stattdessen sollte jeder Code, der sich auf eine bestimmte Weide beziehen muss, die ID der Weide verwenden; Nur die Methoden addPasture() und getYieldFor() (und möglicherweise removePasture() , falls Sie über eine solche Methode verfügen) müssen auf die tatsächlichen Pasture -Objekte zugreifen, die in der pastures -Karte gespeichert sind.

    
Ilmari Karonen 10.09.2015 15:24
quelle

Tags und Links