我已经按层次结构组织了我的代码,并发现自己使用以下代码爬上树.
File clientFolder = task.getActionPlan().getClientFile().getClient().getDocumentsFolder();
我没有钻进这个task
物体; 我正在向它的父母钻研,所以我认为我在封装方面没有失去任何东西; 但是我脑子里的一面旗帜正在告诉我这样做有什么不好的事情.
这是错的吗?
国旗是红色的,它用粗体表示两件事:
为了跟随链,调用代码必须知道整个树结构,这不是很好的封装,并且
如果层次结构发生变化,您将需要编辑大量代码
括号中有一件事:
使用属性,即task.ActionPlan而不是task.getActionPlan()
一个更好的解决方案可能是 - 假设您需要在子级别公开树上的所有父级属性 - 继续并在子级上实现直接属性,即
File clientFolder = task.DocumentsFolder;
这至少会隐藏调用代码中的树结构.在内部,属性可能如下所示:
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 } ... }
但是如果树结构将来发生变化,您只需要更改树中涉及的类中的访问器函数,而不是每个调用链的地方.
[此外,在属性函数中正确捕获和报告空值会更容易,这在上面的示例中省略了]