假设我们在对象内部有一个对象,在另一个对象内部,在两个对象之外检索私有变量值的最佳方法是什么?
最简单的方法似乎是做这样的事情:
$scope.signup.state
这可以接受吗?或者调用调用方法的方法调用方法会更好吗?
考虑到你基本上会在3个不同的类中创建相同的方法,第二个选项似乎不必要地费力。
答案 0 :(得分:2)
使用getter获取任何对象
ex:Object obj = object1.getObject2()。getObject3();
答案 1 :(得分:2)
这取决于您对“可接受”的定义。在你的情况下可能是可以接受的。没有适当的背景,很难分辨。
但是,有些事情你可以考虑,逐级:
虽然这种吸气剂仍然远远不能令人满意,但它仍然比使用直接属性访问更好
即。不是通过直接字段访问来访问object1.object2
,而是在Object2 getObject2()
中提供Object1
,以便代码如下所示:
object1.getObject2().getObject3().getValue()
通常当我们链接这种类型的属性导航时,我们会遇到一些问题,即在某种程度上返回null,这会导致object1.getObject2().getObject3().getValue()
抛出NPE。
如果您使用的是Java 8,请考虑返回Optional<>
。例如在Object1
中,object2
的getter应该看起来像Optional<Object2> getObject2()
通过这样的更改,您的代码可以通过以下方式保持安全:
Value value = object1.getObject2()
.flatMap(Object2::getObject3)
.map(Object3::getValue)
.orElse(Value.emptyValue())
为了实现更松散耦合的设计,您可能希望提供value
API中Object1
的访问权限,而不是暴露多个间接层。因此:
Value value = object1.getFooValue();
(如果符合您的需要,请继续使用Optional<>
)
在内部从Object3
检索值。 (当然,Object2
也可能想要做类似的事情)
永远记住,您应该尽量避免提供对象的内部表示。您的对象应该提供有意义的行为,而不是简单地充当您获取或设置数据的值对象。这里很难举一个例子,但问问自己,为什么需要获得价值?该操作更适合由您的对象本身提供吗?
答案 2 :(得分:1)
最好的方法是不要将对象视为数据存储。应该定义一个类来完成一些工作,一些相关的职责。为了执行该工作以履行这些职责,可以保留一些内部数据,并且包含一些嵌套对象。一般来说,提供数据不应该是对象的目标。
encapsulation中object-oriented programming的全部想法是不公开内部数据和嵌套对象。而是通过在较高/外部对象上声明方法来发布各种可用的杂项。封装使您可以在不破坏外部调用代码的情况下更改这些内部构件 - 避免脆弱性是目标。
例如,Invoice
对象可以包含LineItem
个对象的集合。反过来,每个LineItem对象包含产品,数量,价格,扩展成本,税收,税率,税额和行成本的其他对象。如果您想知道项目中添加的销售税总额,而不是询问LineItem的Invoice,然后询问LineItem以获取TaxAmount对象,请将此杂项定义为Invoice上的方法getTotalTaxAmount
。让这个方法弄清楚(并保持自己!)如何通过包含的对象来收集相关信息。
如果绝对必须公开嵌套数据,请再次定义最高级别的方法,该方法返回所需数据的副本或所需对象的集合(可能是这些对象的副本)。同样,目标是避免在对象内暴露对象。
然后,在Raaga所述的最高方法中,如the correct Answer所述,定义一个调用getter的getter。
在非常简单的数据结构中,您可以直接访问对象。但通常使用getter方法更好。原因再次是封装。使用getter方法可以灵活地重新定义存储数据的实现细节。
例如,目前你可以存储&#34; Sex&#34;变量为String,值为&#34; F&#34;或&#34; M&#34;。但是后来你可能会决定利用Java的漂亮enum feature。所以你要替换那些单字符&#34; F&#34; &安培; &#34; M&#34;包含枚举实例Sex.FEMALE
和Sex.MALE
的字符串。使用吸气剂可以提供一定程度的绝缘,因此可以在内部使用枚举替换字符串。 getter方法继续返回一个String(并在内部将枚举转换为&#34; F&#34;或&#34; M&#34;要返回的String)。这样,您就可以在不破坏那些依赖外部对象的情况下重构您的类。
答案 3 :(得分:0)
object1.object2.object3.getvalue();
这种链接似乎不正确......在这种情况下的对象链接始终是object1.someMethod()。someOtherMethod()。或者使用getter object1.getObject2()。getObject3()在回答中建议的内容。 我希望它有所帮助。
答案 4 :(得分:0)
您所描述的内容可能是最简单的方法(如果可以访问object2
和object3
),但绝对不是这样。正如Raaga所指出,getter在检索一个类的成员方面要好得多,然后这些成员应该是private
或protected
以防止错误。
如果可以的话
object1.object2.object3.getvalue();
您也可以执行类似
的操作object1.object2 = null;
很可能不是你想要的。这是面向对象编程的基本概念之一。类应该处理它们的实现细节/秘密,而不是直接提供给外部!这就是getters / setter的用途。
通过这种方式,您可以更好地控制访问权限,可以执行哪些操作以及无法执行哪些操作。如果您应该只能从object2
检索object1
但无法更改null
,则您只能提供一个getter而不是setter。
如果您还应该能够更改它,那么最好使用setter来进行更多控制,因为您可以检查setter以防止我将object2
指针放在{{{{{ 1}}
如果您担心调用方法的效率可能不如直接访问成员那么高效,那么您可以依赖Java来内部优化您的方法调用,它不会比直接访问慢。