要避免的类(代码完成)

adr*_*anm 38 class-design code-complete

我对代码完整书中的段落感到有些困惑.

在"要避免的类"一节中,它写着:

"避免使用动词命名的类只有行为但没有数据的类通常不是一个类.考虑将类似DatabaseInitialization()或StringBuilder()的类转换为其他类的例程"

我的代码主要由没有数据的动词类组成​​.有发票阅读器,价格计算器,消息构建器等.我这样做是为了将每个类集中到一个任务.然后我将依赖关系添加到其他类以获取其他功能.

如果我正确理解了段落,我应该使用代码

class Webservice : IInvoiceReader, IArticleReader {
    public IList<Invoice> GetInvoices();
    public IList<Article> GetArticles();
}
Run Code Online (Sandbox Code Playgroud)

而不是

class InvoiceReader : IInvoiceReader {
    public InvoiceReader(IDataProvider dataProvider);
    public IList<Invoice> GetInvoices();
}

class ArticleReader : IArticleReader {
    public ArticleReader(IDataProvider dataProvider);
    public IList<Article> GetArticles();
}
Run Code Online (Sandbox Code Playgroud)

编辑 感谢所有回复.

我的结论是,我目前的代码比OO更多SRP,但它也受到"贫血领域模型"的影响.

我相信这些见解将来会对我有所帮助.

Ash*_*Ash 20

像InvoiceReader,PriceCalculator,MessageBuilder,ArticleReader,InvoiceReader类名实际上不是动词名.它们实际上是"名词代理 - 名词"类名.见代理商名词.

作为动词,类名称会是这样的验证,操作,管理等.显然这些都是作为方法更好地利用并会为类名称相当尴尬.

"名词代理 - 名词"类名的最大问题在于它们对类的实际作用(例如UserManager,DataProcessor等)几乎没有意义.结果他们更容易臃肿并失去内部凝聚力.(参见单一责任原则).

因此,具有IInvoiceReader和IArticleReader接口的WebService类可能是更清晰,更有意义的OO设计.

这为您提供了简单明了的名词类名"WebService",以及"名词代理 - 名词"接口名称,它清楚地宣传了WebService类可以为调用者做些什么.

您可能还可以通过为另一个名词添加前缀来为实际类赋予更多含义,例如PaymentWebService.

但是,在更具体地描述类可以为调用者执行的操作时,接口总是比单个类名更好.随着类变得越来越复杂,新接口也可以添加有意义的名称.

  • 我同意你在这里所说的一切,尽管书中的示例确实引用了诸如“StringBuilder”之类的代理名词(讽刺的是.NET Framework实际上具有这个确切的类)。与“WebService”相比,“InvoiceReader”告诉我更多有关该类用途的信息。 (2认同)
  • @Aaronaught,是的,我可能会使用比WebService更具体的名称,例如PaymentWebService,以提供更多的用法.然而,接口是描述类的功能的关键部分.他们可以更精确地在更细粒度的水平上做到这一点,甚至更多,因为类的大小增加(即可以添加更多接口). (2认同)

Aar*_*ght 11

我个人无视这个"规则"..NET框架本身就充满了"动词"类:TextReader,BinaryWriter,XmlSerializer,CodeGenerator,StringEnumerator,HttpListener,TraceListener,ConfigurationManager,TypeConverter,RoleProvider...如果你认为框架设计不当,然后通过各种手段,不要使用类似这些名字.

史蒂夫的意图是可以理解的.如果你发现自己只是为了执行一项特定的任务而创建了几十个类,那么它很可能是一个贫血领域模型的标志,应该能够自己做这些事情的对象不是.但在某些时候,你必须在"纯粹的"OOP和SRP之间做出选择.

我的建议如下:如果你发现自己创建了一个"动词"类,它作用于单个"名词"类,请诚实地思考"名词"类是否可以自己执行动作.但是,不要开始创造God Objects,或者为了避免使用动词类而提出毫无意义/误导性的名称.

  • .NET框架就是这样一个框架.大多数人都没有编写框架,他们的类的名称应该反映出来. (9认同)

Dan*_*nas 5

不要盲目听从任何建议.这些只是指导方针.

也就是说,只要名词模拟逻辑对象,名词就会成为非常好的类名.由于"Person"类是所有"Person"对象的蓝图,因此将其称为"Person"非常方便,因为它允许您这样推理:"我将根据用户的输入创建Person,但首先我需要验证它......"

  • 甚至没有这个建议;) (6认同)