【问题标题】:Alternatives to -Info class name suffix-Info 类名后缀的替代方案
【发布时间】:2013-07-30 15:27:06
【问题描述】:

我一直在阅读 Robert C. Martin 的 Clean Code,无意中发现了一句臭名昭著的声明:

避免使用 Manager、Processor、Data 或 Info 之类的词 类。

所以,很自然地,我尝试将-Info 排除在我的一个班级名称之外。现在,我看到了各种各样的 StackOverflow 问题,询问在 -Manager-Processor 的情况下该怎么做。我见过 cmets 表示他们想不出-Data 会成为一个好的班级名称的时间。好吧,在我看来,-Data-Info 似乎更难区分。特别是,例如在下面的课程中。

我有一个Server 类,如下所示:

public class Server {
    //What I would call ServerInfo
    private int id;
    private String name;
    private String address;
    private int port;
    private int connections;
    private int maxConnections;
    private int status;

    //Bunch of members that aren't ServerInfo, for example:
    private ConcurrentHashMap<String, File> files = new ConcurrentHashMap<String, File>();
    private List<String> filePaths = new List<String>();
    /* ... */

    public void start() { /* ... */ }
    public void stop()  { /* ... */ }
}

有一个HashMap存储了这些服务器的信息,如下在另一个远程服务器上:

public class ServerMap {
    ConcurrentHashMap<Integer, Server> serverMap = /* ... */;
}

但是,这个HashMap只需要知道我所说的就是上面的ServerInfo。它不需要通过存储一堆它永远不会使用的变量来浪费内存。因此,需要一个 Data 类来容纳这些变量。

public class ServerInfo {
    private int id;
    private String name;
    private String address;
    private int port;
    private int connections;
    private int maxConnections;
    private int status;
}

ServerMap 现在变成了ConcurrentHashMap&lt;Integer, ServerInfo&gt;

问题在于这显然违反了清洁代码中的规则。我可以将-Info 更改为某个同义词,但是,这不是真正解决问题吗?例如,我可以称之为ServerDetails,但我看不出它与ServerDataServerInfo 有何不同。

我可以在不同的命名空间中重新定义Server,并只给它这些成员,但这似乎更令人困惑。

对此的最佳实践解决方案是什么?

【问题讨论】:

  • 如果不需要使用“非 ServerInfo 的成员群”,那么为什么要将它们放在 Server 中?你能举出更多关于他们的例子吗?
  • @Genzer 它们被Server 使用。包含有关每个 Server 的信息的地图不使用它们。只有ServerInfo 中的变量需要ServerMap 知道/存储。

标签: java naming-conventions code-cleanup


【解决方案1】:

我认为该声明的重点是避免在涉及类命名时使用诸如 -Data 和 -Info 之类的重载术语。我认为将 ServerDetails 之类的东西用于您要命名的对象是不合适的。毕竟,他们不是这样的吗?

如果 ServerDetails 过于笼统,请问问自己它们是什么类型的信息/详细信息...在这种情况下,它们看起来都与网络或连接相关。 ServerConnectionProperties 或类似的东西怎么样?

完全使用作者提出的指导方针;指导方针。请记住,有很多人有很多意见,但很少有人能 100% 地应用。试图将每一个“最佳实践”应用到信中,你会发疯的。

【讨论】:

  • 这对我来说似乎很合理。作者如此绝对地陈述它,我觉得这是一些需要 100% 遵守的规则——就好像我的代码中存在一些固有的设计缺陷,因为我找不到遵循它的方法。
  • 我不能怪你。每次我接触新事物时,我总是在挖掘“最佳实践”指南以使我保持在前进的道路上,但这会导致很多头疼。我尝试做一些研究,选择一条道路,然后从那里开始。诚然,我发现自己有时也会掉进兔子洞。
  • 您如何看待ServerStateServerSnapshot,因为它是Server 在给定时刻的快照/状态。
  • 如果这就是它所捕捉到的,我觉得它们听起来不错。
【解决方案2】:

我认为您以错误的方式看待重构。他们对ServerInfo 的正确名称(在我看来)将是Server,因为这就是服务器的实际情况。当我们处理 OOP 时,“基础”对象是带有数据的对象。例如,我们不会调用具有用户名、电子邮件和密码UserInfoUserData 的类,因为数据隐含在它具有成员的类这一事实中。 显然,这条规则有一些例外。使用ProfileData 对象来包含某些对用户不太重要的信息是常见的做法。

我个人可以通过两种方式重新考虑这个服务器问题。 一个是我会将基础(serverInfo)重命名为Server,将更高级别的对象重命名为ServerCommands(我很难找到合适的名称,因为我不知道该类所做的一切)

我的下一个建议是基于“泛化”的想法。我们不想命名类的最大原因是因为它概括了编程的隐含方面。几乎所有类都倾向于关联“信息”和“数据”。这是什么信息或数据?我想引用讨论“助手”和“经理”重构的 SO 主题。

原因:像“ThreadHelper”这样的类名让人想知道为什么 需要以及为什么它不能只是“线程”类的一部分。是吗 实际上是适配器还是装饰器?如果是这样,请这样命名。是类 “线程”已经承担了太多的责任?如果是这样,重构和 给新类一个有意义的名字。 “帮手”什么也没说 它正在做或如何提供帮助。

这一切都与课程的实际预期目的有关。如果我看到一个名为 serverInfo 的类,我可能会也可能不会理解该信息是什么。 我个人将其命名为ServerProperties。听起来可能只是信息的同义词,但实际上更具体。当我们想到属性时,我们会想到不会改变的“一次性设置”细节。 (或者如果他们确实改变了,那是因为我们正在改变设置)。你也可以叫它ServerSettings,但我个人更喜欢属性。

【讨论】:

  • 不过,它们并不是一成不变的设置细节。例如,connections 会随着更多连接的进入而改变。我排除的一个属性(偶然)是status,它表示服务器是在线、离线、锁定、加载等。这也会改变。此信息只是整个Server 对象的一小部分,并且仅此信息需要存储在ServerMap 中,而不是存储整个Server 对象。 SettingsPropeties 都传达了与意图不同的上下文。也许现在你可以推荐其他人了?
  • 当我查看这些细节时,在这种情况下(现在我看到更多细节)我会做的是让 serverInfo 类似于 BasicServer 然后将 Server 类设置为类似于 ServerWithFilesFileServer 或类似的东西。 (或反映它包含的额外数据的东西)您甚至可以使 FileServer 扩展 BasicServer 以便稍后您可以创建具有不同扩展成员的不同服务器类
  • 然后将BasicServer的实例存储在ServerMap? ServerMap 存在于不同的盒子上,因此,将在那里存在的BasicServer 的实例不会引用存在于其他地方的实例。这就是为什么包含在ServerMap 中的此类仅包含所需的相关数据很重要的原因。我现在倾向于将其命名为ServerState。感谢您的回复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
相关资源
最近更新 更多