2

Our new project just started and we have a problem related to its architecture.

We have a 3 layer arhitecture:

  1. WebUI
  2. Business
  3. DataRepositories

Each layer has reference only to the layer below it. The communication is done with what we call entities and business objects (BO) as follows:

DataRepositories <--entities--> Business <--BO--> WebUI

<--X--> means communication using objects of type X.

So we have for example UserEntity as entity and User as BO. Another type is ticket which again has TicketEntity and Ticket.

Currently we have some distinct vertical slices through the layers having something like Accounts for users in DataRepositories, Business and WebUI which are well defined and don't interact with the other slices like Tickets.

Now the problem is that a ticket has an buyer which is an user and we don't know where in our architecture we should connect tickets and users. Should the business components interact between them or the data layer should map the user to the ticket?

To be more specific, we have a method for creating a ticket that is resides in Business and is called from WebUI. It takes as arguments the details of a ticket and "the user" which we don't know yet if it should be an object of type user or just the username/id. If we pass a user object that the presentation should get the user before calling CreateTicket. But, if the webui passes the id then the business layer should resolve the user object which would require adding a reference to the Users business component in Tickets (Business).

AdamB
  • 21
  • 1

1 Answers1

2

Personally, I hate parallel hierarchies like this. You've created what you're calling entities, which should have some behavior associated with them, plus a parallel hierarchy of business objects that should be immutable and without any behavior.

I'd dispense with the business objects. I suspect that they aren't providing any value that you can cite besides immutability and someone else's notion of "architectural purity".

I also don't like the direction of the arrow between entities and repositories. I'd have the repositories know about entities, but not the other way around. Why should an entity know or care if it's persisted? The business logic and behavior should be unchanged.

I'd have the view layer interact with services. These are UI agnostic, but they contain all your business logic to fulfill use cases. If you throw away your UI - and you will every few years - your services will remain in place for as long as the business problem does.

The data layer should be responsible for its own referential integrity. If a ticket needs to JOIN to find its user, then you have to have it in the data layer. When the persistence tier queries for a user, it'll also get the tickets that belong to that user and return the one-to-may relationship in the objects. A User will have a List or Set of Ticket instances. All this should be done in the service layer. The service will orchestrate the persistence, business objects, and other services it needs to fulfill the use case.

duffymo
  • 305,152
  • 44
  • 369
  • 561