ric*_*din 7 java refactoring law-of-demeter optional
当我查看一些代码时,我遇到了这个代码片段.
List<User> users = /* Some code that initializes the list */;
users.stream()
.filter(user -> user.getAddress().isPresent())
.map(/* Some code */)
// And so on...
Run Code Online (Sandbox Code Playgroud)
方法的调用user.getAddress()返回一个Optional<Address>.遵循着名的德米特法则(LoD),上面的代码并不干净.但是,我无法弄清楚如何重构它以使其更清洁.
第一次尝试可能是向User类中添加一个方法hasAddress(),但是这种方法克服了拥有Optional<Address>IMO 的需要.
我该如何重构上面的代码?在这种情况下,是否值得满足LoD?
编辑:我错过了在map方法中指定我不想返回地址.
好吧,你自己总结得很好:如果你想通过引入 来更松散地耦合hasAddress(),为什么要返回Optional.
仔细阅读 LoD 的说法,它谈到对“密切相关”单位的了解“有限”。对我来说听起来像是一个灰色地带,但更进一步,它还提到了“只有一个点”规则。不过,我同意对您的问题的评论,即空检查(或isPresent())完全没问题(哎呀,真正的空检查从技术上讲甚至不需要点 ;P )。
如果你想真正封装更多,你可以getAddress()完全删除并提供:
class User {
private Optional<Address> address;
boolean hasAddress() {
return address.isPresent();
}
// still exposes address to the consumer, guard your properties
void ifAddressPresent(Consumer<Address> then) {
address.ifPresent(then::accept);
}
// does not expose address, but caller has no info about it
void ifAddressPresent(Runnable then) {
address.ifPresent(address -> then.run());
}
// really keep everything to yourself, allowing no outside interference
void ifAddressPresentDoSomeSpecificAction() {
address.ifPresent(address -> {
// do this
// do that
});
}
}
Run Code Online (Sandbox Code Playgroud)
但正如评论者指出的那样:值得/有必要吗?所有这些法律/原则很少是绝对的,并且比教条更具有指导意义。在这种情况下,可能是关于平衡 LoD 与 KISS。
最后,由您决定此特定示例是否受益于将流的功能移至 User 类中。两者都是有效的,可读性/可维护性/清洁性取决于:
| 归档时间: |
|
| 查看次数: |
633 次 |
| 最近记录: |