A对象包含B对象,B对象包含C对象,而C对象又包含D对象.我需要从A对象开始访问D对象的"name"属性.
目前,我是这样做的:
a.getB().getC().getD().getName();
个
我可以通过这种方式获得"name"值,但我想知道是否有更好的方法.
任何例子或建议都将不胜感激.
A对象包含B对象,B对象包含C对象,而C对象又包含D对象.我需要从A对象开始访问D对象的"name"属性.
目前,我是这样做的:
a.getB().getC().getD().getName();
个
我可以通过这种方式获得"name"值,但我想知道是否有更好的方法.
任何例子或建议都将不胜感激.
您的解决方案很好,但存在调用的其他对象为空的风险.为了防止出现这种情况,您可以使用NullPointerExceptions
.您可以使用可选判断或显式空判断:
Optional.ofNullable(a.getB())
.map(B::getC)
.map(C::getD)
.map(D::getName)
.orElse(null);
我在 comments 中也看到了Low of Demeter的建议.据我所知,这是一个旨在减少软件开发中组件之间耦合的指导方针.在面向对象编程的上下文中,它建议对象应该只与其直接的"朋友"交互,而不是与陌生人或其他对象的内部细节交互.
当应用于方法调用时,Demeter定律通常意味着对象方法应该只调用以下方法:
所以我试着用这个原则来做到这一点:
// Class A encapsulates a reference to an instance of class B.
public class A {
private B b;
// This method demonstrates adherence to the Law of Demeter by only interacting with its direct friend, B.
// It checks if B is non-null and then delegates the responsibility of getting D's name to B.
// This avoids directly accessing the internals of B or its relations.
public String getDName() {
if (b != null) {
return b.getDName();
}
return null; // Returns null if B is null, avoiding a NullPointerException.
}
}
// Class B encapsulates a reference to an instance of class C.
public class B {
private C c;
// Similar to class A, this method follows the Law of Demeter by interacting only with its direct friend, C.
// It delegates the task of retrieving D's name to C, thus not violating the principle by reaching out to C's internals.
public String getDName() {
if (c != null) {
return c.getDName();
}
return null; // Handles the case where C is null gracefully.
}
}
// Class C encapsulates a reference to an instance of class D.
public class C {
private D d;
// Adhering to the Law of Demeter, this method interacts only with its immediate friend, D.
// It directly retrieves D's name if D is not null, demonstrating a direct and simple interaction with its component.
public String getDName() {
if (d != null) {
return d.getName();
}
return null; // Protects against null D references.
}
}
// Class D holds a name property.
public class D {
private String name;
// Direct accessor method for the name property.
// This is the endpoint of the delegation chain and does not need to follow LoD principles as it does not delegate further.
public String getName() {
return name;
}
}