All*_*nde 6 architecture design-patterns law-of-demeter method-chaining
我已经按层次结构组织了我的代码,并发现自己使用以下代码爬上树.
File clientFolder = task.getActionPlan().getClientFile().getClient().getDocumentsFolder();
Run Code Online (Sandbox Code Playgroud)
我没有钻进这个task
物体; 我正在向它的父母钻研,所以我认为我在封装方面没有失去任何东西; 但是我脑子里的一面旗帜正在告诉我这样做有什么不好的事情.
这是错的吗?
国旗是红色的,它用粗体表示两件事:
括号中有一件事:
一个更好的解决方案可能是 - 假设您需要在子级别公开树上的所有父级属性 - 继续并在子级上实现直接属性,即
File clientFolder = task.DocumentsFolder;
Run Code Online (Sandbox Code Playgroud)
这至少会隐藏调用代码中的树结构.在内部,属性可能如下所示:
class Task {
public File DocumentsFolder {
get { return ActionPlan.DocumentsFolder; }
}
...
}
class ActionPlan {
public File DocumentsFolder {
get { return ClientFile.DocumentsFolder: }
}
...
}
class ClientFile {
public File DocumentsFolder {
get { return Client.DocumentsFolder; }
}
...
}
class Client {
public File DocumentsFolder {
get { return ...; } //whatever it really is
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是如果树结构将来发生变化,您只需要更改树中涉及的类中的访问器函数,而不是每个调用链的地方.
[此外,在属性函数中正确捕获和报告空值会更容易,这在上面的示例中省略了]
世界上最大的旗帜。
您无法轻松检查这些调用中的任何一个是否返回空对象,因此几乎不可能跟踪任何类型的错误!
getClientFile() 可能会返回 null,然后 getClient() 将失败,当您捕捉到这一点时,假设您正在尝试捕捉,您将不知道哪一个失败了。