class-designcode-complete

Classes to avoid (code complete)


I am somewhat confused about a paragraph in the code complete book.

In the section "Classes to avoid" it reads:

"Avoid classes named after verbs A class that has only behavior but no data is generally not really a class. Consider turning a class like DatabaseInitialization() or StringBuilder() into a routine on some other class"

My code mainly consists of verb classes without data. There are invoicereaders, pricecalculators, messagebuilders etc. I do this to concentrate the classes to one task each. Then I add dependencies to other classes for other functionality.

If I understand the paragraph correctly I should use code like

class Webservice : IInvoiceReader, IArticleReader {
    public IList<Invoice> GetInvoices();
    public IList<Article> GetArticles();
}

rather than

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

class ArticleReader : IArticleReader {
    public ArticleReader(IDataProvider dataProvider);
    public IList<Article> GetArticles();
}

Edit Thanks for all the replies.

My conclusion is that my current code is more SRP than OO but that it also suffers from the "anemic domain model".

I'm sure theses insights will help me in future.


Solution

  • Class names like InvoiceReader, PriceCalculator, MessageBuilder, ArticleReader, InvoiceReader are not actually verb names. They are really "noun agent-noun" class names. See agent nouns.

    A verb class name would be something like Validate, Operate, Manage etc. Obviously these are better used as methods and would be quite awkward as class names.

    The biggest problem with "noun agent-noun" class names is that they can give very little meaning as to what the class actually does (eg UserManager, DataProcessor etc). As a result they are more likely to be bloated and to lose internal cohesion. (See Single Responsibility Principle).

    Therefore the WebService class with the IInvoiceReader and IArticleReader interfaces is probably the clearer and more meaningful OO design.

    This gives you the simple, obvious noun class name "WebService", along with "noun agent-noun" interface names that clearly advertise what the WebService class can do for callers.

    You could probably also give more meaning to the actual class by prefixing another noun, for example PaymentWebService.

    However the interfaces are always better than a single class-name at describing more specifically what the class can do for callers. As the class grows more complex, new interfaces can also be added with meaningful names.