Cqrs vs N-layer

Incoding CQRS vs NLayer

Disclaimer: This article is the author’s personal opinion based on the experience and knowledge gained from creating projects.

The way it used to beе

In recent times the approach of complex n-layer architectures, which segregates an application into layers thus giving developers an option to work out elements of the project separately, has been most often used to develop the server-end of the
business applications.

Yet there are certain drawbacks:

  • The “Expansion” of the initial code, the problem most commonly caused by adding linking layers like facade layer, communication layer.
  •  Concealing details behind a multitude of layers (the problem is thoroughlydescribed in the article ).

Within the n-layer systems the n-layer the service layer, which aims at concealing the details of the enterprise processes and application logic by aggregating similar tasks into one class, at the same time it springs the following problems:

  • Difficulties in maintenance and expansion of closely connected methods (the problem will be considered in more detail in this article
  • The increased complexity of the unit test creation unit test

Another reason for rejecting the n-layer may be considered to be the fact that after such Agile Software Development like Scrum, kanban have gained popularity it turned out that complex multilayer architectures feature a set of other problems::

  • Complexity of the task decomposition due to the high layer coherence,which fact does not let to use the sprint.
  • Abstractions between layers affects negatively the overall architecture transparency, thus hindering the developers’ communication.

Way to CQRS

Software developers came to design of CQRS while solving a decomposition problem and also other problems described above. Therefore CQRS has been chosen as a basis of server architecture for Incoding Framework.

Incoding Framework CQRS is a set of basic and ready classes (command, query, dispatcher, Event broker) which completely cover the majority of wide-spread scenarios of business applications development..

Basic terms:

  • CommandBase – basic class for commands
  • QueryBase – basic class for queries
  • IEvent – event implementation
  • IEventSubscriber – implementation of event subscribers
  • DefaultDispatcher – default dispatcher for command and queries implementation
  • DefaultEventBroker – default broker for message publications

Note: most Incoding Framework implementations can be substituted for your own with IoC.

Key classes for developers are CommandBase и QueryBase, which feature the following instruments:

Note: the major difference between commands and queries when working with database is that queries never perform commit ( submit changes ) to the database while commands do..

Further on in the article we are considering a solution for a typical task basing on the example of the API development for the Order creation, which is gradually getting more sophisticated, illustrating the advantages and disadvantages of various
approaches..

Task 1

Issue::  creation of order

Solution: service layer

note: business logic

note: use service

Solution: Incoding CQRS

note: business logic

note: use command

Conclusion: implementation of the Incoding CQRS scores appreciably at the expense of:

  • Provided infrastructure ( repository , dispatcher )
  • A single execution point of all command и query, which makes redundant doubling the uniform code in multiple service method (like implementation of the Unit of work)

Note : in case of services this is only possible when using AOP (Aspect oriented programming).
Note:the example code is prepared for creating UNIT TEST which is testified by introducing interactions into the class constructor which are supposed to be further substituted for place holders

Task 2


Issue:  edition of order

Solution: service layer

 note: business logic

 note: usage service

Solution: Incoding CQRS

note: business logic

note: usage command

Conclusion: Task complication makes it obvious that the expansion of UserService class is made difficult as it is impossible to consider Add and Edit tasks separately (low segregation level) which consequently leads to the high level of elements coherence thus complicating the following:

  • Altering one task skipping the others;
  • Creating unit test (the example of the algorithm service layer demonstrates that it turned out necessary to add one more interface IOrderRepository in accordance with the constructor, although it is not used in the Add method)
  • Responsibility distribution between the developers within the same group

Task 3


Issue:  sending an e-mail upon creating or editing order

solution: service layer

 note: business logic

Solution: Incoding CQRS

 note: business logic

 notes: events

 note: subscribers

Conclusion: solution involving Incoding Framework may seem slightly more difficult due to responsibility segregation (saving in the database from sending e-mail), but this very characteristics allows testing each of the elements separately and reusing the events from various commands and queries. (In case of services this is achieved through inheritance, but faces a set of problems considered below in the conclusion to the paper)

Note: only changes in services and commands running are described here, the controller remaining unchanged.

Conclusion

Having considered the task solutions one may see than the cqrs approach (Incoding CQRS in particular) is more favorable for segregation of the tasks into smaller absolutely atomic (independent) blocks, than for any similar solutions based on
service layer implementation

The major reason for choosing Service layer is often the possibility to use the OOP, especially inheriting one service class from another one, thus extending functionality with general techniques, and giving the possibility to get rid of duplication. Consider GetUser or Get Staff techniques as examples. They can be used in most services and for this reason are included into the basic class UserServiceBase, from which specific implementations such as OrderService are inherited afterwards. However this approach features certain problems concerning maintenance of the inheritance in the subsequent application expansion, because either the subclasses won’t implement the techniques of the basic class or will introduce certain Boolean variables into their pattern (signature) or polymorphic overloading, thus leading to the following problems:

  • Low method coherence within the class
  • High level of complexity when altering or testing the code.

Under the module testing, task segregation into different classes can be distinguished, thus allowing independent task testing. Controller testing comes easier, taking just one parameter into the constructor (IDispatcher through which all the business logic of the application is processed).

Easy and comfortable communication with customers, as well as maintenance of the flexible methodologies of the implementation should also be pointed out to because of:

  • Minor commands and query allow building up the sprint with high decomposition level.
  • Commands and queries are a prototype of a business action, like “Add Order”, “Approve payment”, “Confirm user” or others.

Bill of materials on CQRS

Bill of materials on implementation of the Incoding Framework CQRS

  • Ready-made testing application  IncMusicStore
  • The Browsio project, which brings out its full potential
  • Official documents
  • Any questions are welcome in the comments to this topic or using contact details indicated on the site.

P.S. Incoding Framework CQRS has been tested for flexibility in various complicated business applications of the company.

Vlad Kopachinsky

I am a Senior developer at Incoding Software in Russian Federation. I created the Incoding Framework for rapid development

More Posts - Website - Twitter - Facebook - LinkedIn

Leave a Reply