Hi Lukasz,
I think the best way to think about use cases or commands, is to think it act as coordinator. it doesn't do anything, just coordinate the entities to achieve a goal. The main responsability of a UC is organize the application logic. For a simple example, imagine a blog system. We can have 4 important concepts: author, reader, article and comment and 2 use cases: publish an article and comment an article. How we can implement these use cases to coordinate the application logic? So I'm big fan of domain driven design, then my implementation is very influenced by this. Let's take a look at the "publish article" use case.
class PublishArticle
def execute(author_id, title, text)
author = author_repository.get_by_id(article_id)
article = author.write(title, text) ## article_factory.create(title, text)
author.publish(article)
all_articles.save(article)
end
end
It is a very simple example, but the use case doesn't know how to publish the article. If the logic is simple or complex, it is not the use case responsability . Another important point is the use of the business language to add responsability to entities. The article.write method, makes more semantic the flow. In a anemic model way, I think, it can be similar to this:
class PublishArticle
def execute(author_id, title, text)
article = Article.new
article.title = title
article.text = text
article.author_id = author_id
article.published = true
article.published_at = DateTime.now
save_article(article)
end
end
In this implementation, we don't have the advantage to use the flow to increase the abstraction level. I put a very simplified logic to publication here, just for ilustrate the problem, but it can be more complex than this. Another important point, is in this case, the use case to know all the logic to publication, if it changes, the use case change too.
Here another implementation example:
class CommentArticle
def execute(reader_id, article_id, comment_text)
reader = reader_repository.get_by_id(reader_id)
article = article_repository.get_by_id(article_id)
comment = reader.comment(article,comment_text)
article_repository.save(article)
end
end
Again, I would like to highlight the flow. This use case doesn't know how a comment is created, how a comment is saved, etc.
This is a very simple domain, and I thought 10 minutes about this to write this answer, so, there more interesting domains to apply this style.
It was helpful?