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.
但是,在更具体地描述类可以为调用者执行的操作时,接口总是比单个类名更好.随着类变得越来越复杂,新接口也可以添加有意义的名称.
Aar*_*ght 11
我个人无视这个"规则"..NET框架本身就充满了"动词"类:TextReader,BinaryWriter,XmlSerializer,CodeGenerator,StringEnumerator,HttpListener,TraceListener,ConfigurationManager,TypeConverter,RoleProvider...如果你认为框架设计不当,然后通过各种手段,不要使用类似这些名字.
史蒂夫的意图是可以理解的.如果你发现自己只是为了执行一项特定的任务而创建了几十个类,那么它很可能是一个贫血领域模型的标志,应该能够自己做这些事情的对象不是.但在某些时候,你必须在"纯粹的"OOP和SRP之间做出选择.
我的建议如下:如果你发现自己创建了一个"动词"类,它作用于单个"名词"类,请诚实地思考"名词"类是否可以自己执行动作.但是,不要开始创造God Objects,或者为了避免使用动词类而提出毫无意义/误导性的名称.
不要盲目听从任何建议.这些只是指导方针.
也就是说,只要名词模拟逻辑对象,名词就会成为非常好的类名.由于"Person"类是所有"Person"对象的蓝图,因此将其称为"Person"非常方便,因为它允许您这样推理:"我将根据用户的输入创建Person,但首先我需要验证它......"