Java 嵌套对象最佳实践

Java 嵌套对象最佳实践,java,object,nested,reference,Java,Object,Nested,Reference,引用嵌套对象的最佳实践是什么 假设我有以下几点: class Outer { private InnerA innerA; //getters and setters } class InnerA { private InnerB innerB; //getters and setters } class InnerB { private String someString; //getters and setters } 在我的控制器或服务类中,我需要检查InnerB

引用嵌套对象的最佳实践是什么

假设我有以下几点:

class Outer {
 private InnerA innerA;
 //getters and setters
}

class InnerA {
  private InnerB innerB;
  //getters and setters
}

class InnerB {
  private String someString;
  //getters and setters
}
在我的控制器或服务类中,我需要检查InnerB类的someString变量,以确保它不为null或不为空,因此我执行以下操作:

if (getOuter().getInnerA().getInnerB().getSomeString() != null && !getOuter().getInnerA().getInnerB().getSomeString().equalsIgnoreCase("") {
  //do something
}
在我看来,这看起来很混乱,如果嵌套对象本身为空,可能会有问题


我是否在父对象中为检查null的子对象创建getter和setter?只是想知道最好的实践是什么,如果有的话,和/或你们中的一些人在代码中做了什么?

我认为Outer的用户不应该知道Outer.InnerA.InnerB.SomeString——它被埋藏得太深了。如果不接触外部3层分离的客户机,就无法更改InnerB的实现——那么,即使使用内部类又有什么意义呢?你所描述的情况是丑陋的,不应该出现

我建议你先考虑一下某个字符串是属于InnerA还是外部的。< /P> 现在假设您的层次结构是正确的,但SomeString具有外部客户端所需的唯一属性(如果SomeString不是唯一的,那么层次结构肯定是错误的)。在本例中,使用Outer.getSomeString(),或者更好的是使用Outer.isSomeStringNullOrEmpty(),这样至少Outer的客户端不必知道InnerA和InnerB


PS.someString.equalsIgnoreCase(“”)很昂贵,不要使用它。更便宜的是someString.length()==0这很乱,但如果你只需要在一个地方做,我可能会接受它。否则,我将实现一个
Outer.getSomeString()
,它隐藏内部路径,因为外部类是作为接口公开的类


这还允许您处理中间内部类之一为null的情况,而无需每次尝试访问
someString

时进行大量顺序检查。当然,如果这些对象中的任何一个可以为null,那么您必须在调用此对象的getter之前检查null

但是这种链接是缺乏封装的一种坏味道(缺乏数据、没有行为的对象)。你违反了:不要和陌生人说话。

你有两个选择:

  • 使用
  • 等待Java7空安全运算符

  • 我的信念是,您不应该通过外部类的方法公开“内部”成员,除非您正在为它们添加某种功能或不同的行为,或者该值对于外部类的使用是“必不可少的”。然而,这也是一个判断的问题,并且可以根据代码的使用和体系结构而有所不同


    另一方面,如果您希望长字符串调用的代码“不那么难看”,我建议投票支持在下一版本的Java中添加for项目coin(我希望它已经变成7:-()。

    您可以使用Apache Commons BeanUtils在嵌套属性中导航,如下所示:

    将方法
    getSomeString()
    添加到外部类,并编写如下代码

    PropertyUtils.getNestedProperty(这是“innerA.innerB.someString”);

    我不记得那个
    PropertyUtils
    类是否检查空属性,但我会查看这个站点


    希望这对您有所帮助!

    我建议您阅读。

    我已经编写了一个Java 8方法:

    public class Helper {
        public static <IN, OUT> OUT returnNullOrCallFunction(IN o, Function<IN, OUT> f) {
            return o == null ? null : f.apply(o);
        }
    }
    
    如果
    myObject.getSomeOtherObject()
    null
    该方法将返回
    null
    ,否则它将调用
    myObject.getSomeOtherObject().toString()

    这非常有用,如果你只需要更深一层

    对于多层,它变得丑陋:

    Helper.returnNullOrCallFunction(
            Helper.returnNullOrCallFunction(
                    myObject.getSomeOtherObject(),
                    SomeOtherObject::getAnotherObject
            ),
            AnotherObject::toString
    );
    

    这是java的一个限制。 如果父对象“OuterObject”有助于减少代码重复,则应在其中实现帮助器方法

    此帮助器方法对于聚合其他对象的对象非常有用,并且仅当嵌套值存在时才需要检查

    代码:

    它将执行所有空检查

    从*.xsd生成的对象经常出现此问题。 在一个复杂的xml结构中,经常会有许多嵌套的可选节点,而有趣的是最后一个节点。 然后最好编写帮助器方法,这些方法将回答节点是否存在以供重用的问题

    如果达到你的cod样本,我通常会这样写

    if (hasSomeString(getOuter())) {
      //do something
    }
    

    所以,
    PersonDAO.getPerson(123.getAddress().getCity().loadMap())
    这是一个错误吗?你能评论一下Nishant的问题吗?这是一种气味,不是证据。Demeter定律是一个原则,通常很好遵循,但不一定总是这样。它有优点和缺点。在Nishant的例子中,你可以有一个loadMap()直接亲自授权给它的地址。它甚至可以实现一个可映射的接口。OP的示例有些不同,因为它所做的只是访问数据。我建议您熟悉映射到POJO的XML文档的奇妙世界。这只是一个LoD根本不适用的示例。
    getOuter().hasInnerB();
    
    if (hasSomeString(getOuter())) {
      //do something
    }