Ich habe fast alle Fragen mit dem Tag des Demeter gelesen. Meine spezifische Frage wird in keiner dieser anderen Fragen beantwortet, obwohl sie sehr ähnlich ist. Hauptsächlich meine Frage ist, wenn Sie ein Objekt mit Kompositionsschichten haben, aber die Eigenschaftswerte von den verschiedenen Objekten abrufen müssen, wie erreichen Sie das und warum gehen Sie einen Ansatz vor einen anderen?Wie arbeiten das Demeter-Gesetz und die Komposition mit Sammlungen zusammen?
Angenommen, Sie haben ein ziemlich Standard-Objekt haben von anderen Objekten zusammengesetzt, wie folgt aus:
public class Customer {
private String name;
private ContactInfo primaryAddress;
private ContactInfo workAddress;
private Interests hobbies;
//Etc...
public getPrimaryAddress() { return primaryAddress; }
public getWorkAddress() { return workAddress; }
public getHobbies() { return hobbies; }
//Etc...
}
private ContactInfo {
private String phoneNumber;
private String emailAddress;
//Etc...
public getPhoneNumber() { return phoneNumber; }
public getEmailAddress() { return emailAddress; }
//Etc...
}
private Interests {
private List listOfInterests;
}
Die folgende verletzen würde sowohl das Gesetz von Demeter:
System.out.println("Phone: " + customer.getPrimaryAddress().getPhoneNumber());
System.out.println("Hobbies: " + customer.getHobbies().getListOfInterests().toString());
Dies würde auch das Gesetz verstoßen von Demeter, denke ich (Klarstellung?):
ContactInfo customerPrimaryAddress = customer.getPrimaryAddress();
System.out.println("Phone: " + customerPrimaryAddress.getPhoneNumber());
Also vermutlich, du wou ld dann fügen Sie ein "getPrimaryPhoneNumber()" Methode Kunde:
public getPrimaryPhoneNumber() {
return primaryAddress.getPhoneNumber();
}
Und dann rufen Sie einfach an: System.out.println ("Telefon:" + customer.getPrimaryPhoneNumber());
Aber im Laufe der Zeit scheint es, als würde es tatsächlich eine Menge Probleme bereiten und gegen die Absicht des Demeter-Gesetzes arbeiten. Es macht die Customer-Klasse zu einer riesigen Tüte Getter und Setter, die viel zu viel Wissen über ihre eigenen internen Klassen hat. Zum Beispiel scheint es möglich, dass das Kundenobjekt eines Tages verschiedene Adressen (nicht nur eine "primäre" Adresse und eine "geschäftliche" Adresse) haben wird. Vielleicht wird sogar die Customer-Klasse einfach eine Liste (oder eine andere Sammlung) von ContactInfo-Objekten anstelle von bestimmten benannten ContactInfo-Objekten haben. Wie gehst du in diesem Fall weiterhin dem Demeter-Gesetz nach? Es scheint den Zweck der Abstraktion zu besiegen. Zum Beispiel scheint dies sinnvoll in einem solchen Fall, in dem ein Kunde eine Liste der Contact Artikel hat:
Customer.getSomeParticularAddress(addressType).getPhoneNumber();
Dies scheint, wie es noch verrückter bekommen kann, wenn man über einige Leute denken, ein Mobiltelefon und ein Festnetz-Telefon mit, und dann muss ContactInfo eine Sammlung von Telefonnummern haben.
Customer.getSomeParticularAddress(addressType).getSomePhoneNumber(phoneType).getPhoneNumber();
In diesem Fall beziehen wir uns nicht nur auf Objekte innerhalb von Objekten innerhalb von Objekten, aber wir müssen auch wissen, was die Gültigkeit des address und Phone die sind. Ich kann definitiv ein Problem mit diesem sehen, aber ich bin nicht sicher, wie man es vermeidet. Vor allem, wenn irgendeine Klasse dies anruft, weiß sie wahrscheinlich, dass sie die "mobile" Telefonnummer für die "primäre" Adresse des Kunden in Frage stellen wollen.
Wie könnte dies umgestaltet werden, um dem Demeter-Gesetz zu entsprechen und warum sollte das gut sein?
ich glaube, Sie es zu wörtlich, es ist nur eine Richtlinie für möglichen Code riecht einnehmen. Was Sie tun, ist in Ordnung. – Esailija
Stimmen Sie mit Estagija überein, das Gesetz des Demeter muss nicht wirklich auf Getters angewendet werden, sie sind zu trivial. Tatsächlich würde das, was Sie vorschlagen (Customer.getPrimaryPhoneNumber()), dazu führen, dass der Kunde die Interna von ContactInfo kennen muss. Der Vorteil von Kompositionstypobjekten besteht darin, dass Sie einschränken, wer über ContactInfo Bescheid wissen muss, z. – Taylor
OK, ich sehe diesen Punkt, aber in meinem Kopf wird es Nicht-Getter/Setter-Szenarien für das Zeug in ContactInfo geben. Angenommen, Sie möchten den Kunden per E-Mail über einen Link oder eine Schaltfläche informieren. Sie könnten es wie customer.getSomeParticularContactInfo (addressType) .sendEmail() oder customer.sendEmail() schreiben, die dann (innerhalb des Kunden) getSomeParticularContactInfo ("primär"). SendEmail() aufruft. Oder es gibt andere Optionen wie eine Manager-Klasse, die die Aktion behandelt. In dem Beispiel geht es dann nicht um Getter oder Setter, und ich bin verwirrt darüber, wie man in diesem Kontext Designentscheidungen trifft. –