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定律通常意味着对象方法应该只调用以下方法:

  1. 对象本身(此).
  2. 对象作为参数传递给该方法.
  3. 它创建/实例化的任何对象.
  4. 其直接组件对象(通常称为其属性或字段).

所以我试着用这个原则来做到这一点:

// 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;
    }
}

Java相关问答推荐

Cucumber TestNG Assert失败,出现java. lang. Numbercycle异常

使用Java Streams API比较两个不同的Java集合对象和一个公共属性

在现代操作系统/硬件上按块访问数据值得吗?

如何粘合(合并)文件Lucene?

Java FX中的河内之塔游戏-在游戏完全解决之前什么都不会显示

在JavaFX项目中注册组合框的控件FX验证器时,模块系统出错

如何在Java中从XML中获取特定的 node ,然后将其删除?

从ActiveMQ Classic迁移到ActiveMQ Artemis需要进行哪些客户端更改?

WebSockets和Spring Boot安全性出现错误401

Kotlin Val是否提供了与Java最终版相同的可见性保证?

有谁能帮我修一下这个吗?使输出变得更加整洁

通过Java列表中的某些字段搜索值

Java 21中泛型的不兼容更改

在Java泛型中使用通配符时,如何推断类型

如何使用WebEnvironment.RANDOM_PORT获得第二个随机端口?

如何在Maven Central上部署?

Java 17与Java 8双重表示法

PhantomReference无法访问时会发生什么?

人们在 IntelliJ 上将-Dhttp.proxyHost=your.proxy.net -Dhttp.proxyPort=8080放在哪里?

如何在 Android Studio 中删除 ImageView 和屏幕/父级边缘之间的额外空间?