Gibt es objektive Argumente für oder gegen die Verwendung von Objekten gegen eindeutige ID als Methoden- / Funktionsparameter? (und Mitglieder anderer Objekte?). Speziell im Kontext statisch typisierter Sprachen (C # / Java / Scala)
Vorteile des Objekts selbst:
- Weitere typsichere Anrufe. Bei IDs besteht die Gefahr einer falschen Reihenfolge der Argumente. Dies kann jedoch gemindert werden, indem für jede Klasse eine 'Mini'-Klasse beibehalten wird, in der nur die ID dieser Klasse gespeichert ist.
- Holen Sie sich einmal aus Ausdauer, keine Notwendigkeit, wieder zu bekommen
- Wenn sich bei ID der ID-Typ ändert, z. B. int -> long, ist eine allgemeine Änderung mit der Möglichkeit von Fehlern erforderlich. (Courtsey: https://softwareengineering.stackexchange.com/a/284734/145808 )
Vorteile der Verwendung von ID:
- Meistens wird das eigentliche Objekt nicht benötigt, sondern nur eine eindeutige ID. Wenn Sie also eine ID haben, sparen Sie Zeit, wenn Sie es aus der Persistenz herausholen.
Eine Mischung dieser Techniken hätte, soweit ich sehen kann, nur Nachteile von beiden und Vorteile von beiden.
Da dies ein konkret definiertes Problem ist, hoffe ich, dass es objektive Antworten gibt und nicht die Typen "Ich denke" oder "Ich mag" ... :-).
BEARBEITEN: Kontext auf Vorschlag eines Kommentators - Die einzige Einschränkung sind statisch typisierte Sprachen. Die Anwendung ist eine Allzweckanwendung, freut sich jedoch über Antworten, die auch auf bestimmten Verwendungsszenarien basieren.
EDIT: Noch etwas Kontext. Angenommen, ich habe ein Buchverwaltungssystem. Mein Modell ist:
Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}
Table- wishlist: { isbn: String, memberId: Int}
Table- borrows: { id: Int, memberId: Int}
Method:
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int, memberId: Int)
handleBorrowRequest( memberId: Int, book: Book ){
//the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing.
}
Warum sollte ich nur den Ausweis und nicht das Vollmitglied behalten wollen? Wenn ich Informationen über ein Buch erhalte, muss ich selten wissen, wer es gespendet oder ausgeliehen hat. Es ist ein Overkill, die vollständigen Informationen zu erhalten, um die Felder "SpendedBy" und "BorrededBy" zu füllen.
Natürlich sind dies nur meine Punkte. Ich bin mir sicher, dass mir Dinge fehlen, also wollte ich wissen, was die Punkte dafür / dagegen sind.
Antworten:
Abhängig von Ihrer Umgebung und Ihrem Problemkontext kann die Notwendigkeit, in die Datenbank zu wechseln, verringert werden. Infolgedessen geht das Argument (IMO) für die Verwendung nur von IDs verloren.
Zum Beispiel hat PHPs Doctrine2 ORM
EntityManager::getReference
, das einen träge geladenen Proxy für eine Entität unter Verwendung der angegebenen ID erzeugt; Ich weiß nicht, wie viele andere ORMs das tun, aber es entspricht in etwa der von Ihnen erwähnten Vorstellung einer "Miniklasse". In den meisten Fällen handelt es sich um eine vollständig hydratisierte Einheit, sodass Sie sie weitergeben und wie jede andere verwenden können.Der einzige Fall, in dem dies nicht der Fall ist, ist die Angabe einer ungültigen ID. In diesem Fall möchten Sie zur Validierung trotzdem zur Datenbank gehen. Um die Kosten für das Abrufen von Entitäten zu senken, verfügen die meisten ORMs über Caching-Funktionen (erste und zweite Ebene), die in irgendeiner Form verfügbar sind.
Sobald wir den Bedarf und die Kosten für den Zugriff auf die Datenbank reduziert haben, bleibt uns weitgehend der Vorteil, die Entität als Parameter zu verwenden:
Natürlich gibt es Fälle, in denen man möglicherweise nur eine ID übergeben möchte: zum Beispiel beim Überschreiten einer begrenzten Kontextgrenze (im domänengesteuerten Design sprechen). Wenn wir zwei begrenzte Kontexte mit unterschiedlichen Vorstellungen davon betrachten, was ein Konto ausmacht (z. B. Finanzen oder Kundenbeziehungen), können wir das Konto von Kontext A nicht an Kontext B übergeben. Stattdessen kann eine Konto-ID (in der Sprache der Domäne) verwendet werden übergangen werden.
quelle
Für diese Art von Frage delegiere ich an die Lösung, die meine Absicht als Programmierer am besten kommuniziert, und mache die Arbeit von "Future Greg" am einfachsten.
Die Verwendung des Objekts als Argument erleichtert es, den Methodenaufruf in 6 Monaten richtig zu machen, und ich habe die Details dieser Anwendung vergessen. Um auf Ihrem "Ist dieses Buch im Wunschliste-Beispiel dieser Person" aufzubauen, nehmen wir an, dass die
isInWishList
Methode wirklich nur die ganzzahligen IDs von Büchern und Mitgliedern vergleichen muss. In der Realität benötigt diese eine Methode nur zwei Daten, um ihre Aufgabe zu erfüllen. Lassen Sie uns nun einen Schritt von dieser einen Methode zurücktreten und das gesamte Softwaresystem betrachten. Ich bezweifle, dass für den Betrieb nur eine Buch-ID und eine Mitglieds-ID erforderlich sind. Sie werden ohnehin das vollständige Buch und Mitglied aus der Datenbank ziehen, bevor Sie das aufrufen,isInWishList
da Sie wahrscheinlich mehr tun müssen, als nur diese eine Methode aufzurufen. Vielleicht tust du das, aber meistens musst du mehr tun.Angesichts dessen werden Sie nicht realistisch einen Leistungsverlust erleiden, wenn Sie beide Objekte vollständig aus der Datenbank abrufen und zuordnen. Theoretisch benötigen Sie weniger Datenbankaufrufe, aber in der Praxis werden Sie feststellen, dass dies einfach nicht stimmt. Wenn Sie diese IDs als Parameter in der Abfragezeichenfolge an den Server zurückgeben, müssen Sie nur die Wunschliste aus der Datenbank abrufen. Dies ist jedoch eine sehr enge Ansicht Ihrer gesamten Anwendung. Es gibt Szenarien, in denen Sie neben der Überprüfung einer Wunschliste auch andere Vorgänge ausführen, z. B. ein Buch zu einer Wunschliste hinzufügen. Sie möchten keine doppelten Elemente hinzufügen.
Entscheiden Sie sich für die Lösung, die für einen neuen Programmierer oder Ihr zukünftiges Selbst am einfachsten zu verstehen ist, nämlich das Übergeben von
Book
undMember
Objekten. Erst nachdem Sie ein tatsächliches Leistungsproblem gefunden haben, sollten Sie sich wirklich darum kümmern, nur die IDs zu übergeben.Oder wir können uns daran erinnern, dass statisch typisierte Sprachen wie Java eine Methodenüberladung bieten, sodass Sie Ihren Kuchen haben und ihn auch essen können:
Die eigentliche Antwort auf diese Frage besteht darin, beide Methoden zu schreiben, die Nur-Ganzzahl-Version aus der stark typisierten Version aufzurufen und Bob ist Ihr Onkel.
quelle