1
votes

To give you a quick overview of my application architecture, I have the following layers in my application:

  • Domain Model - Models the problem domain and business rules.
  • Service Model - Models the service contract consumed by the application.
  • Data Access Layer - Persistence of domain models, in this case using EF.
  • Services - Implementations of the service model.
  • Website - MVC web application.
  • Web API - RESTful web service API.

Now the problem is that the Web API came later; the MVC web application was the first thing that was built on top of the architecture.

I find myself having to replicate business logic and ViewModels (MVC) and Messages (Web API)...According to the DRY principle, I shouldn't be doing this, so the natural solution is to push the business logic into its own layer which is independent of the application layers.

But...this means that the business logic layer needs it's own set of models which sit between the application layer and the business logic layer. In this respect, it would not be applicable to use domain models, since these really shouldn't ever hit the application layer.

So in short, I'm looking for an industry accepted standard for business logic modelling. Is there an accepted standard for how this should work, and if so, what type of model (i.e. it's not a domain model, and it's not a view model) belongs to the business logic layer?

1
"I find myself having to replicate business logic and ViewModels (MVC) and Messages (Web API)..." I really do not get why you would have to duplicate anything really. How adding a Web API has anything to do with business logic? The Web API should just be seen as a port to reach the application service layer over HTTP. ViewModels have nothing do do with application services or web apis, they are UI-related and should live in the Website only (the same goes for any MVC component), it's UI stuff.plalx
@plalx say for example I want to create a new product in my store. In MVC I have NewProductViewModel and in WebAPI I have NewProductRequestMessage. They both contain the same properties. Both solutions have the same code to persist the information, and return the same responses. DRY has been violated, thus, moving the models and business logic into its own layer and sharing it makes sense, but I was just wondering whether there was a common pattern for this.Matthew Layton
Before the Web API you were supposed to have View->Controller->Services->Domain Model. If the web application now uses the web API you can have View->Controller->Web API->Services->Domain Model. The View/Controller part can be omitted if your UI doesn't use MVC and the MVC part can either be client-side (SPA) or server-side.plalx
@plalx what happens if I then want to for argument sake, add a WPF, Windows Forms or Console application that also require the same models and business logic?Matthew Layton
@seriesOne "Both solutions have the same code to persist the information". That makes no sense at all? It seems that you have all these layers but actually do not understand what is their purpose. With the layers you have in place there shouldn't be any duplication at all. The ViewModel is a completely different thing than a DTO returned by the application layer, which is a completely different thing than a domain object. If they accidentally happen to all have the same structure then perhaps that is because you have a simple CRUD application. Nevertheless, they do not have the same purpose.plalx

1 Answers

1
votes

You have stumbled upon a contested point of discussion. I myself have struggled with this for a long time.

Object bigots will argue that you shouldn't even have a service layer. Your domain model could then be directly consumed which would eliminate the duplication of logic. Granted, those were the good old days of software modeling. With the advent of the web, apis and SOAs, we are forced to look at alternative ways of modeling our software. Enter Anemic Domain models.

Anemic Domain models essentially consist of light weight objects that resemble DTOs more than anything, with underlying services that do the heavy lifting.

The architecture you have described above seems to be a hybrid design. I am guessing by now you must have run into the issue of mapping EF classes to domain objects, which creates yet another layer of objects, unless you use POCOs, in which case you run into namespace issues and what not.

Anyways, I don't think there is an industry standard. What I can tell you is that I have seen a few patterns emerge here and there leaning towards Anemic Domain Models and it's not hard to see why. In disconnected environments (e.g. web, API), complex objects don't work very well, hence the affluence of services.

Since you have layered your application nicely and do not wish to expose your domain model objects, I would suggest using Anemic Models in your service implementations. These would essentially function as DTO objects that can be reused and serialized if the need be, but can also implement basic logic that may even map back to functionality implemented in the services.

On a final note, there is no one-size-fits-all. Use the right tool for the job. Patterns are meant to be guidelines, not step-by-step instructions, so make sure you feel free to tweak them in order to fit your particular needs while retaining the general idea.

You can read more about Anemic Domain Models here: https://en.wikipedia.org/wiki/Anemic_domain_model

Make sure to check out Martin Fowler's objections to Anemic Domain Models as well: http://www.martinfowler.com/bliki/AnemicDomainModel.html