假设我们在一个对象内有一个对象,在另一个对象内,在这两个对象外检索私有变量的值的最佳方法是什么?
最简单的方法似乎是这样做:
object1.object2.object3.getvalue();这可以接受吗?或者调用一个调用方法的方法会更好,这个方法调用一个方法?
考虑到你基本上会在3个不同的类中创建相同的方法,第二种选择似乎不必要地费力。
发布于 2015-12-07 14:41:09
使用getter获取任何对象
例如: Object obj = object1.getObject2().getObject3();
发布于 2015-12-07 15:32:19
这取决于你对“可接受”的定义。在你的情况下,这可能是可以接受的。如果没有适当的上下文,就很难判断。
但是,您可能会逐级考虑以下几点:
1.使用getter
尽管这种getter方法还远远不能令人满意,但它仍然比使用直接的属性访问要好。
也就是说,不是通过直接的字段访问来访问object1.object2,而是在Object1中提供Object2 getObject2(),这样代码看起来就像:
object1.getObject2().getObject3().getValue()2. Null处理
通常,当我们链接这样的属性导航时,我们会遇到在某种程度上返回null的问题,这使得object1.getObject2().getObject3().getValue()抛出NPE。
如果您使用的是Java8,请考虑返回Optional<>。例如,在Object1中,object2的getter应该类似于Optional<Object2> getObject2()
有了这样的更改,您的代码可以通过如下方式使其为空安全:
Value value = object1.getObject2()
.flatMap(Object2::getObject3)
.map(Object3::getValue)
.orElse(Value.emptyValue())3.德米特定律
为了进行更松耦合的设计,您可能希望在Object1的API中提供对value的访问,而不是公开多级间接。因此:
Value value = object1.getFooValue();(如果适合您的需要,请继续使用Optional<> )
在内部,它从Object3中检索值。(当然,Object2可能也想做类似的事情)
4. Getter是邪恶的
请始终记住,您应该尽量避免提供对象的内部表示。您的对象应该提供有意义的行为,而不是简单地充当获取或设置数据的值对象。在这里很难给出一个例子,但是问问你自己,为什么你需要获取的值?该操作是否更适合由您的对象本身提供?
发布于 2015-12-07 15:20:20
最好的方法是不要把你的对象看作是数据存储。一个类应该被定义为有一些工作要做,一些相关的职责集群。为了执行这项工作来履行这些职责,可能会保留一些内部数据,并包含一些嵌套对象。一般来说,服务数据不应该是您的对象的目标。
封装
object-oriented programming中encapsulation的整个思想是不公开内部数据和嵌套对象。相反,通过在更高/外部对象上声明方法来发布各种可用的琐事。封装使您可以在不破坏外部调用代码的情况下更改这些内部结构-目标是避免脆弱性。
例如,Invoice对象可以包含LineItem对象的集合。反过来,每个LineItem对象又包含产品、数量、价格、扩展成本、可税性、税率、税额和额度成本的其他对象。如果您想知道所有项目的增值税总额,而不是询问发票,然后向LineItem询问TaxAmount对象,请将此杂务定义为LineItem上的方法getTotalTaxAmount。让该方法找出问题(并保持其自身!)如何遍历所包含的对象以收集相关信息。
如果一定要公开嵌套数据,请再次在最高级别定义一个方法,该方法返回所需数据的副本或所需对象的集合(可能是这些对象的副本)。同样,目标是避免暴露对象中的对象和对象中的对象。
然后,在最高的方法中,如the correct Answer by Raaga所述,定义一个调用getter的getter。
Getter方法与直接成员访问
在非常简单的数据结构中,您可以直接访问对象。但通常使用getter方法会更好。同样,原因是封装。通过使用getter方法,您可以灵活地重新定义存储数据的实现细节。
例如,目前您可以将"Sex“变量存储为值为"F”或"M“的字符串。但是以后您可能会决定利用Java的漂亮的enum feature。因此,您可以用枚举实例Sex.FEMALE和Sex.MALE替换这些单字符"F“和"M”字符串。拥有一个getter可以提供一定程度的隔离,因此String可以在内部替换为枚举。getter方法继续返回一个字符串(并在内部将枚举转换为要返回的"F“或"M”字符串)。这样你就可以在不破坏那些依赖的外部对象的情况下重新构建你的类。
https://stackoverflow.com/questions/34127741
复制相似问题