New course: Refactoring from Anemic Domain Model Towards a Rich One



My new training course Refactoring from Anemic Domain Model Towards a Rich One went live.

Refactoring from Anemic Domain Model Towards a Rich One

I’m back to the topic of Domain-Driven Design with my video courses. This one is devoted to the specific problem many programmers face when they are stuck with anemic domain models. It is an in-depth, step-by-step guideline of how to turn your domain model into a rich, highly encapsulated one.

From this course, you will learn:

  • Why Anemic Domain Model is an anti-pattern.
  • The relationship between Anemic Domain Model and Functional Programming.
  • What encapsulation is and how to achieve it in your domain model.
  • A ton of refactoring techniques.

In the course, you will see a fully-fledged ASP.NET Core 2.0 API project written with the anemic domain model anti-pattern in mind. We will then dissect and refactor it piece by piece. I encourage you to follow along the course and do all the refactorings with me to achieve the best retention.

Watch the course here: Refactoring from Anemic Domain Model Towards a Rich One.

Share




  • ajukraine

    Sounds like an exciting course! Will give it a try.

  • Andrii Chubariev

    Thank you!
    What a coincidence, just yesterday was my first day at a new very important job, had to cross The Atlantic to work here. After I’ve inspected the codebase one of the biggest issue was exactly the anemic model. And you know what, the last day I’ve read your blog was about a 1.5 month ago. So now I open it and, BAM, new course about getting rid of anemic models!

    Have not checked it yet, but I am sure it is 5*.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Huh, that’s a nice coincidence indeed! Congrats on the new job!

  • Anderson GM

    Hi Vladimir,

    Congratulations for publishing one more course! I believe I’m reading your blog since I’ve watched your DDD in practice, which I think is the best course on the subject available on Pluralsight. I really enjoy your pragmatic approach to solve problems.

    If you don’t mind, I would like to give you a suggest about how to help the learners make the most of the course. Instead of showing the solution for the problem, maybe you could only give some directions and ideas about how to solve the situation – let’s call it a challenge. Then, the student could give it a try and then check your solution after. In other words, move from passive study to active.

    I only saw it in one course on Pluralsight. IMHO, I think it is the way to go.

    *I didn’t watch this specific course, so maybe you already did something like that. Sorry if it was the case.

    Best regards

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you for the kind words, happy to hear the course was of that much value for you.

      That’s a really interesting idea! I too find that active learning provides the best results. Could you give a link to this course which does that? It would be interesting to try to incorporate this practice in my further courses.

  • Roger Brogan

    Hi Vladimir,

    First off, fantastic blog and courses on Pluralsight. I find this course particularity relevant and helpful. I hope this is the correct place to put this question. The course uses the example web API and a typical client would likely be an Angular application. How do you manage code duplication in your domain model on the typescript angular application with similar domain rules on the C# web API side?

    For example, I want to implement similar business rules in my angular application to give a good user experience. I don’t want to have to make a call to the back end for each interaction as the latency would hurt performance. But you will need to enforce the same or similar rules on the back end as we need to protect the data before it is stored. Your thoughts on this would be very helpful.

    Thanks,
    Roger

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Hi Roger, thanks, glad you liked the course.

      To avoid the domain knowledge duplication, you could implement some sort of hypermedia approach where the API sends the UI both the data and the validation rules/available actions associated with that object. For example, not just
      { “name”: “John”, zipCode: “12345” }
      but
      { “name”:
      { “value”: “John”, “maxLength”: 50, validationRule: “” },
      zipCode: { … },
      actions: [ “promote”, “delete” ] }

      And the UI will need to build an interpreter for those rules/actions. This is not always feasible, though, and sometimes it’s just easier to duplicate that knowledge, so be pragmatic here.

      The decision boils down to the deployment model. If the UI can be deployed at the same time as the API, than the duplication is mostly fine. If not (e.g. in case of an app in Apple’s App Store), then the fulle-fledged REST hypermedia model is necessary.

      • Roger Brogan

        The metadata idea is very clever. I had not considered an approach like that thanks for the idea. I also appreciate your pragmatism. As you suspected the domain is complex enough that the metadata approach may not fully solve the problem. Specifically, I have some validation requirements that depend on external systems that can change outside of my application. This creates some interesting challenges as I must protect my system from changes in other systems that would cause my application to fail. So, I must check and then recheck as certain times to guard against this. I am not intentionally being vague but contractually I cannot speak publicly in detail about what the application does.
        I forked your repository for the anemic domain model class and added a simple angular client to test out some proof of concepts. The code is by no means production ready or even complete, but it is there if you want to take a look. I wanted to choose a simple approach first and then see how moving the domain logic to the client would work out. I found some interesting things.
        1. The validation rule of unique email per customer requires communication to the database so it cannot be fully done on the client without a server call.
        a. Also, this rule is implemented in the controller layer. Is this the right place or would a domain services layer be appropriate?
        b. I have similar validation requirements in my application regarding unique names for certain things over varying scopes. So, an elegant solution here is of interest to me.
        c. My simple approach on the client side uses a client call and an angular async validator. This works but it is not very DDD in my opinion.
        2. When I was about to implement the promote customer method in the angular project it dawned on me I did not have an easy way to construct the Customer object without an actual repository. I could write a local repository that retrieved information from the server but I then have to keep that in sync. I could use a local EF like framework like Breeze.js to do this but even though I like Breeze it is very opinionated and does not seem to be under active development. I am curious as to your opinions on this topic.
        Other solutions I am contemplating are going to immutable state with the redux pattern with ngrx and comparing the angular UI to a React UI.
        I will continue to work on my thought experiments and I really appreciate your comments and insights.
        Thanks,
        Roger

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          1. There will be cases where you wouldn’t be able to move all the validation logic from the client. And that’s fine, it shouldn’t be your goal anyway. The goal here is to make the client have as little business logic as possible. Potential additional roundtrip to the server is not an issue in that sense. What you want to avoid is the logic like

          if (customer.Status == 1)
          enablePromoteButton();
          else
          disablePromoteButton();

          because this is a clear leakage of the domain knowledge from the server to the client (the knowledge what actions are available to what types of customers).

          So, make the call to the server and parse any errors it returns. I would implement a separate endpoint to verify the uniqueness only if the business explicitly wants a separate async check before submitting the form. And even in this case, I would post the whole object, not just the email part of it.

          2. The idea I had in mind when working on the sample project was that you will get the list of customers via the “GET /customers” call and so the only thing you’d need to promote a customer is his Id. Which is part of what the API returns. Why would you need to construct a Customer object?

          • Roger Brogan

            Why would you need to construct a customer object? That is the question I am pondering. The approach of keeping all the domain business logic in the server is certainly a good one from several perspectives. It keeps only one copy of the domain logic and it keeps the client code simple. Like the image below.

            https://uploads.disquscdn.com/images/5c587bbc2b4206120dbde31eb3cac55a7a3282b2056357417df3288126b1aa1e.png

            However, the project requirements are demanding more rich user experiences. Specifically, they are asking for field level asynchronous validation not only on simple unique names but other more complicated scenarios. For example, filling out certain information optionally creates new validation rules like making sure an IP address is valid for a specific subnet mask and certain rules cascade differently based on prior selection. Some of these require communication back to the server but I am trying to minimize that to keep the UI responsive.
            So, I envisioned a smart version of the client that models the domain logic. Like the image below.

            https://uploads.disquscdn.com/images/d7e6047ab088328833599be46c7ce5a3561eee39e457f70a92e172dcc99f0e71.png

            The problem is then keeping the data in sync between he client and server. Maybe I am making this too complex but I think this model has merit. Thoughts?

          • http://enterprisecraftsmanship.com/ Vladimir Khorikov

            Well, it looks like you’ll need to make a trade-off here and implement at least some of the business logic on the client as well. But again, if your UI is going to be deployed together with the API, it shouldn’t be a problem. One of the main reasons to keep the UI clueless about the business logic is that this way you’ll be able to decouple the two and deploy them separately. Duplication is a lesser issue here.

  • Xavier L.

    Hi Vladimir,

    Thanks for this very interesting course:)

    I have a question about making the constructors private and relying on static methods to build instances. That seems really promising from the pure DDD point of view, but how do you mix that and unit tests ?
    If your domain objects hold some behavior and you want to use them in unit tests you’re supposed to mock them, to not use their behavior in the tests.

    I read your article on mocks, and I kind of agree, but the claim that code should be tested in isolation remains a valid one also. And I currently don’t have a full freedom when it comes to unit tests policy…

    What would you do in this situation to solve the problem and meet the best of both worlds, or which would be in your mind the best compromise that could be done to reach a point somewhere in the middle ?

    Thanks,
    Xavier

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      the claim that code should be tested in isolation remains a valid one also

      As a side note: there are two definitions of isolation. The first one states that the SUT itself (say, a class) should be tested in isolation from other classes. The second – that the unit tests should be able to run in isolation from each other. The first one entails the need in mocking for all dependencies. The second – only for volatile dependencies (DB, external APIs, etc). It’s also the difference between the mockist and classicist approaches.

      In your situation, you could probably add those dependencies in the static factory methods. This will enable mocking pretty much the same way as it would should you use constructors directly. It’s hard to provide more details without seeing the code example. You can send me one for a review, maybe I would be able to answer in more detail.

  • http://auct.eu/ Dima Taras

    great course! Although I’m using other lang I wonder how you would cache it?

    For example you have rich model that is used in standart web (razor views) and dtos for api. Currently im making dtos which fullfill needs of my razor views + api and cache only dtos objects, but I don’t know if it is right approach. In my case my rich model has some helper methods and with my approach I need to copy that methods to other service for razor view (I’m using other lang but this stuff almost identical).

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks!

      Technically, DTOs shouldn’t have any logic (methods) in them but if you’ve got the only client for those DTOs which you fully control (this is the case in e.g. a typical client server app where you develop both the API and a JS client), then it’s mostly fine. A purer alternative here would be to create separate utility classes that would accept the DTOs and return the result you need.