I'm trying out a new code structure where I'm splitting all my giant repositories and factories into loads of smaller classes each with a single responsibility. And on top of this I'm using verbs for class names as I think that it's the best way to describe exactly what each class is meant for.
Each class has only one public method (called "Execute"), but often has private methods and sometimes a constructor with arguments.
Examples:
Before:
class DocumentRepository {
public List<Document> GetDocuments()
public void SaveDocument(Document document)
public Document CopyDocument(int id)
}
After:
class GetDocuments {
public List<Document> Execute()
}
class SaveDocument {
public void Execute(Document document)
}
class CopyDocument {
public Document Execute(int id)
}
One benefit of this structure is that I'm much more willing to split the functionality of the public methods into multiple private methods (much easier to read and manage). Before this would increase the clutter in the repository but now the private methods are contained within their separate classes.
I have always read that classes should have nouns as names but when a class only has one use it seems better to name it by what it does.
Question:
Is this a bad idea (both the separation and the naming)? And if so, what is a better way of creating this separation and avoiding large classes?
Edit: It should be noted that I have come to these (weird) ideas from a Command-Query perspective. So maybe it makes most sense to compare it to that instead of repositories.
Though extracting every single method into separate class seems too radical, there is an element of sense in it. For highly loaded systems the Command-Query responsibility segregation (CQRS) principle is being applied. The main idea of it is to strictly separate Queries (idempotent methods, not modifying system state, but only returning data) from Commands (methods that modify system state; in "pure" CQRS they don't even return data - though it is still hard for me to accept this).
Doing so would make your system more stable and easily expandable, as you can have many distributed nodes that do nothing but reading, focusing on performance of a single node that modifies data. However not all systems really need this.
Even if you really need a separate class for single methods, naming it as verb is not a good idea, as it will confuse other developers (staying inside one class it would be hard to determine what you see in code - the other class name or this class' internal method). You don't need to invent your own notation here, just use the following (relatively standard):
class GetDocumentsQuery { }
class SaveDocumentCommand { }
class CopyDocumentCommand { }
More information about CQRS: