java 嵌套对象最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5248691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nested Objects Best Practice
提问by blong824
What is the best practice for referencing nested objects?
引用嵌套对象的最佳实践是什么?
Say I have the following:
说我有以下几点:
class Outer {
private InnerA innerA;
//getters and setters
}
class InnerA {
private InnerB innerB;
//getters and setters
}
class InnerB {
private String someString;
//getters and setters
}
and in my controller or service class I need to check the someString String variable of the InnerB class to make sure it is not null or not empty so I do this:
在我的控制器或服务类中,我需要检查 InnerB 类的 someString String 变量以确保它不为空或不为空,所以我这样做:
if (getOuter().getInnerA().getInnerB().getSomeString() != null && !getOuter().getInnerA().getInnerB().getSomeString().equalsIgnoreCase("") {
//do something
}
To me this looks messy and could have issues if the nested objects themselves are null.
对我来说,这看起来很混乱,如果嵌套对象本身为空,则可能会出现问题。
Do I create getters ans setters in the parent objects for the child objects checking for null? Just wondering what the best practice was if any and/or what some of you do in your code?
我是否在父对象中为检查 null 的子对象创建 getter 和 setter?只是想知道最佳实践是什么和/或你们中的一些人在代码中做了什么?
回答by JB Nizet
If any of those objects can be null, then you have to check for null before calling a getter on this object, of course.
如果这些对象中的任何一个可以为空,那么当然,您必须在对该对象调用 getter 之前检查是否为空。
But this kind of chaining is a bad smell of a lack of encapsulation (anemic objects having just data, and no behavior). You're violating the law of Demeter: don't talk to strangers.
但是这种链接是缺乏封装的不好的味道(贫血的对象只有数据,没有行为)。你违反了得墨忒耳定律:不要和陌生人说话。
回答by kosmoplan
You can use Apache Commons BeanUtils to navigate through your nested properties like this:
您可以使用 Apache Commons BeanUtils 来浏览您的嵌套属性,如下所示:
Add method getSomeString()
to your Outer class and write something like
将方法添加getSomeString()
到您的外部类并编写类似
PropertyUtils.getNestedProperty(this, "innerA.innerB.someString");
PropertyUtils.getNestedProperty(this, "innerA.innerB.someString");
I can't remember if that PropertyUtils
class check null properties, but I would look Apache Commons BeanUtilssite.
我不记得PropertyUtils
该类是否检查空属性,但我会查看Apache Commons BeanUtils站点。
Hope this helps!
希望这可以帮助!
回答by Nishant
回答by John Cromartie
I would recommend reading up on the Law of Demeter.
我建议阅读迪米特法则。
回答by wmlynarski
This is a java limitation. You should implement helper methods in the parent "OuterObject" if it helps you to reduce code duplication.
这是一个java限制。如果可以帮助您减少代码重复,您应该在父级“OuterObject”中实现辅助方法。
This helper methods are useful for object which are aggregating other object and you need to check only if the nested value exists.
此辅助方法对于聚合其他对象的对象很有用,您只需要检查嵌套值是否存在。
Code:
代码:
getOuter().hasInnerB();
Which would do all the null checks.
这将执行所有空检查。
This problem occurs often with objects generated from *.xsd. In a complicated xml structure it happens often that there a many nested optional nodes. And what usually is interesting is the last node. Then its better to write helper methods which will answer the questions if node exists for reuse.
这个问题经常发生在从 *.xsd 生成的对象上。在复杂的 xml 结构中,经常会出现许多嵌套的可选节点。通常有趣的是最后一个节点。那么最好编写辅助方法来回答问题,如果节点存在以供重用。
If it comes up to your cod sample i usually write something like that
如果涉及到你的鳕鱼样本,我通常会写这样的东西
if (hasSomeString(getOuter())) {
//do something
}
回答by M. Jessup
My belief is that you should not expose "inner-inner" members through methods of the outer class unless you are adding some sort of functionality or different behaviour to them or the value is "essential" to the use of the outer class. However this is also a matter of judgement and can vary depending on the use and architecture of your code.
我的信念是您不应该通过外部类的方法公开“内部-内部”成员,除非您向它们添加某种功能或不同的行为,或者该值对于外部类的使用是“必不可少的”。然而,这也是一个判断问题,可能会因代码的使用和架构而异。
On a side note if you want the code for a long string of invocations to be "less ugly" I suggest voting for addition of the Elvis Operatorfor project coin in the next version of Java (I wish it had made it into 7 :-().
附带说明一下,如果您希望一长串调用的代码“不那么难看”,我建议投票支持在下一版本的 Java 中为项目代币添加Elvis Operator(我希望它已成为 7 :- ().
回答by iluxa
I don't think users of Outer should have knowledge of Outer.InnerA.InnerB.SomeString - it's buried to deep. You can't change implementation of InnerB without touching clients of Outer 3 levels separated - so what's the point of even having inner classes? Situations like you're describing are ugly and shouldn't arise.
我认为 Outer 的用户不应该了解 Outer.InnerA.InnerB.SomeString - 它被埋得很深。你不能改变 InnerB 的实现而不接触外部 3 个级别的客户端 - 那么即使有内部类又有什么意义呢?像你所描述的情况是丑陋的,不应该出现。
I'd recommend you first consider whether SomeString belongs in InnerB or InnerA or Outer.
我建议您首先考虑 SomeString 是否属于 InnerB 或 InnerA 或 Outer。
Now suppose your hierarchy is correct, yet SomeString has this unique property of being required by clients of Outer (if SomeString is not unique that way, hierarchy is definitely wrong). In this case, Outer.getSomeString(), or better yet, Outer.isSomeStringNullOrEmpty(), so that at least clients of Outer don't have to know about InnerA and InnerB
现在假设您的层次结构是正确的,但 SomeString 具有这种独特的属性,即 Outer 的客户端需要它(如果 SomeString 不是唯一的,那么层次结构肯定是错误的)。在这种情况下,Outer.getSomeString(),或者更好的是 Outer.isSomeStringNullOrEmpty(),这样至少 Outer 的客户不必知道 InnerA 和 InnerB
PS. someString.equalsIgnoreCase("") is expensive, don't use that. Much cheaper is someString.length() == 0
附注。someString.equalsIgnoreCase("") 很昂贵,不要使用它。便宜得多的是 someString.length() == 0
回答by Kendrick
It's messy, but if you only had to do it in one place then I might live with it. Otherwise, I'd implement a Outer.getSomeString()
that hides the internal path, since your Outer class is the one you're exposing as your interface.
这很乱,但如果你只需要在一个地方做,那么我可能会接受它。否则,我会实现一个Outer.getSomeString()
隐藏内部路径的方法,因为您的外部类是您作为接口公开的类。
This also allows you to deal with a case where one of the intermediary inner classes is null, without having to do a number of sequential checks each time you try to access someString
.
这还允许您处理中间内部类之一为空的情况,而不必在每次尝试访问someString
.
回答by Benjamin M
I've written a Java 8 Method:
我写了一个 Java 8 方法:
public class Helper {
public static <IN, OUT> OUT returnNullOrCallFunction(IN o, Function<IN, OUT> f) {
return o == null ? null : f.apply(o);
}
}
Now you can call:
现在你可以调用:
Helper.returnNullOrCallFunction(
myObject.getSomeOtherObject(),
SomeOtherObject::toString
);
If myObject.getSomeOtherObject()
is null
the method will return null
, else it will call myObject.getSomeOtherObject().toString()
.
如果myObject.getSomeOtherObject()
是null
,方法将返回null
,否则将调用myObject.getSomeOtherObject().toString()
。
That's pretty useful, if you just have to go one level deeper.
这非常有用,如果你只需要更深一层。
For multi level, it gets ugly:
对于多层次,它变得丑陋:
Helper.returnNullOrCallFunction(
Helper.returnNullOrCallFunction(
myObject.getSomeOtherObject(),
SomeOtherObject::getAnotherObject
),
AnotherObject::toString
);