Is an ANEMIC Domain Model really that BAD?

Ғылым және технология

Is an anemic domain model a bad thing? Most would probably call it an anti-pattern, and it should be avoided. But is that really true? Well, it depends on what your intent is. Are you trying to create a domain model? Or are you really just trying to create a data model?
🔗 EventStoreDB
eventsto.re/codeopinion
🔔 Subscribe: / @codeopinion
💥 Join this channel to get access to source code & demos!
/ @codeopinion
🔥 Don't have the JOIN button? Support me on Patreon!
/ codeopinion
📝 Blog: codeopinion.com
👋 Twitter: / codeopinion
✨ LinkedIn: / dcomartin
📧 Weekly Updates: mailchi.mp/63c7a0b3ff38/codeo...
0:00 Intro
0:31 Anemic Domain Model
4:49 Transaction Script
7:08 Domain Model
#softwarearchitecture #softwaredesign #domaindrivendesign

Пікірлер: 86

  • @GothenburgDon
    @GothenburgDon2 жыл бұрын

    You’re hitting on something here that is very interesting to me. I worked mostly within this transaction script as a service methodology but have always thought that they can be hard to compose in a reusable way. I’d love to see a more detailed example of breaking down multiple services (transaction scripts) into better domain models end to end

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Ya good idea for a future video.

  • @ShikaIE

    @ShikaIE

    Жыл бұрын

    @@CodeOpinion 6 months a bit too late here, but I agree with the guy above. It'd be really nice to see end-to-end domain modelling videos on real-life scenarios. I have lots of experience myself but when tutoring or mentoring jr, it'd be good to have a solid video to show this!

  • @moacir8663

    @moacir8663

    Жыл бұрын

    @@CodeOpinion did you already make that video you mentioned?

  • @ernest1520
    @ernest15202 жыл бұрын

    I have to admit that while I've heard the term "transaction script" before, until watching this video I wasn't actually aware that it is indeed a transaction script pattern that I use most often, including in my current project. Thus far I was basically calling it explicitly an anemic domain model, and deliberately so. We've been implementing the exact approach that you have described, i.e. the command-handler pattern, with handlers containing the business logic and making updates on models (data bag objects). This is an approach that IMHO suits best the majority of use cases with low complexity of the business domains, and there is no need for unnecessarily complicating things by "artificially" trying to introduce domain models. As always, great video Derek.

  • @FranckMercado
    @FranckMercado2 жыл бұрын

    Awesome practical explanation! And yes, I think one of the first rules we break when having anemic model is encapsulation. And that means other parts of our code can alter our model's state and that could translate to bugs.

  • @morningstarsci
    @morningstarsci2 жыл бұрын

    This reminds me of the functional approach to domain modeling where there is a separation between data and behavior.

  • @gds03_
    @gds03_2 жыл бұрын

    Dude you SMASH with good info! appreciated. Undoubtly you were almost lauching about Entity Service or Entity Manager - I love that soft skill coming up even in this videos! ahahahah

  • @user-hu1jr6fb9k
    @user-hu1jr6fb9k2 жыл бұрын

    The main problem I've seen with the Services + Anemic Domain Model is, that you have these data bag objects and each of it may be handled by a bunch of different services in some way or another; they pull data from those objects through generously spread getters and make decisions based on that data. It's all fun and games until your data and business rules are changing one day. Now during refactoring you have to trace the data through all those services and figure out how it was used to make which decisions. It's a refactoring nightmare and it would have been so much easier if the object which holds the data would try to not leak it through the whole app but make the decisions on its own.

  • @marna_li

    @marna_li

    2 жыл бұрын

    Hmm. There is a tradeoff in everything. I had a scenario the other day. I wanted the domain object to call a service. So I added a domain service that I pass as a parameter to the method. Think: document.StartSign(signingService, signer) It works for simple cases. But I don’t think that anyone should worry really. Well-structured code is easy to refactor. The questions that I got in a forum at work was from one guy who felt uncomfortable with putting logic in entities. Then there was the worry about versioning. Great questions, though.

  • @alejandroVigano
    @alejandroVigano2 жыл бұрын

    I really liked your concept of Services as TransactionScripts! My believe is that most applications nowadays are representations of business processes. Business depends on transactions, transactions are better built stateless (look at funcitonal programming and stateless scalability) and for me that's the reason anemic domain model is relevant and no bad at all. I can see rich domain model on scenarios where -stateful- is helpful, some frontend frameworks makes a really good use of mutable objects (redux could be a good example). But stateful is dangerous!! Can lead to unexpected consequences if not done right, I try to avoid it at all cost unless is strictly necessary. Thanks for sharing knowledge! 👏🏼

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I've covered domain models in another videos and where they are truly useful. Primarily being a consistency boundary. If you haven't watched this one already, I use the same example kzread.info/dash/bejne/aGiiybJmkbi_gMY.html

  • @alejandroVigano

    @alejandroVigano

    2 жыл бұрын

    @@CodeOpinion amazing!

  • @stevep5759
    @stevep57592 жыл бұрын

    Another great video. I've noticed so much of good software development is isolating cyclomatic complexity from IO devices. I always start my request handlers as a transaction script invoking direct SQL. When I see a cyclomatic complexity score of > 5, calling into another script, or duplication, then I push logic down into pure functions, define a simple repository that maps produced domain events -> SQL and repeat. Would love to see some content on modeling aggregates with pure functions that only produce events. I think it makes modeling Event Sourced aggregates much simpler in comparison to in place mutations.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I did cover this a bit in regards to testing: kzread.info/dash/bejne/pHugsMqSf9Sxis4.html

  • @MrBildo
    @MrBildo2 жыл бұрын

    Before I pushed for DDD in our organization, we were using something almost identical to your transaction script example. Entities had zero methods as a rule. Most of the business rules were in command handlers or services (because these were being inherited/overridden in some cases). When our architecture was designed 10 years ago it felt like the standard, to be honest. I suspect a lot of applications are still being written this way. It's interesting to see DDD become more of the defacto standard, at least it seems that way to me (confirmation bias?).

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I think equally the tactical patterns from DDD get used when they don't need to be at all and a transaction script would work fine. I'm not advocating against them, just the dogmatic approach that's often used. Use it when appropriate (domain complexity).

  • @MrTvdS
    @MrTvdS2 жыл бұрын

    Spot on, once again. One of the advantages of moving the logic from a handler to the model itself, is that you can easily go for a functional core (without the IO). You convinced me to put some serious time in refactoring my project.

  • @carnelyve866
    @carnelyve8662 жыл бұрын

    Excellent content. Even as a vet myself, I still learn a lot from your vids. Do you have a video where you show how how to access the database while at the same time using DDD? Thanks.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I talk about it in this video: kzread.info/dash/bejne/eaiLuKmDoJOcYaQ.html

  • @mabdullahsari
    @mabdullahsari2 жыл бұрын

    05:30 I worked on an app that had controllers newing up other controllers inside of them. I kinda died inside when I saw that. Felt physical pain.

  • @alexas09
    @alexas092 жыл бұрын

    On my end I’ve always been using the anemic model and as you pointed out the issue is often when there is services interdependencies. You can run into circular dependency issues. The way I am doing things today is that I got repositories that return data to the services. Each services is responsible for its entitie’s logic nothing else. Then if services need to call each other to me it is a use case (I call them features). Theses leave on the application layer outside the domain and contains the logic that combine multiple services together. That worked so far but I will definitely try the rich model pattern in a future complex project

  • @alexas09

    @alexas09

    2 жыл бұрын

    Awesome job on the videos by the way

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    When things get complex and you need to isolate and share that complexity that's when transaction scripts and an anemic domain model can get hard to manage. Until that time comes, working with a pure data model can go a long way.

  • @vanivari359
    @vanivari359 Жыл бұрын

    Coming from the Java world, this bothers me for 15 years now, but i haven't seen a single complex application which was able to implement a good and clean domain model approach. It's always this stateless transactional script approach (or a kinda dirty mix) because that's how most of the business works (processes/state machines) and ORM + other frameworks are even hard to use otherwise. Developing and maintaining an intuitive understandable domain model in situations where you might have dozens of connected "Entities" is very hard and requires constant thoughtful naming and refactoring. But the IT business grows too fast and if you need many new people every year (and you are not google) and can't hire only the best developers, this ends in an unreadable and unmaintainable mess fast. The transactional script approach is harder to mess up (still many developers need only weeks to ruin it, if you don't double check everything) and at least your datamodel stays "clean". Also, considering handlers, API-resources, repositories etc are often already following this "service/manager" approach, it often seems pointless to move a tiny bit of logic into the domain especially because often, the domain logic requires further database access or calls to external systems, which makes it hard to test and understand because logic is so distributed. Not hating on the approach, i just haven't seen a good complex implementation, which improved readability/maintainability, but i saw many transactional script structured applications with 20+ years of runtime and thousands of people working on it at the heart of the business of global players and it is still maintainable, so i kinda gave up on the idea.

  • @RasmusSchultz
    @RasmusSchultz2 жыл бұрын

    I have two basic principles I try to follow, when choosing whether to put some logic in an entity or a service. First, if it's validation of any sort, I put it in the entity - preferably in the constructor, but if the entity is mutable, I put it in setters, so they protect against getting your entities into an invalid state; objects that don't protect themselves against invalid states are "too anemic". Second, if a function involves only a single entity, I put it in that entity - if it has no dependencies on any other part of the model, there is no point in making someone search for that functionality elsewhere, or risk them duplicating functionality they couldn't find; objects that aren't in charge of operations exclusively involving themselves are "too anemic". Everything else probably belongs in services or commands etc. - if an operation involves two entities, how do you even decide which entity should own that? I've known developers who would accuse me of writing "anemic" models because I follow these principles. In my opinion, a model is not really "anemic" if it guarantees it's own integrity - if it's not leaking it's own internal concerns anywhere else, it's not a problem. 🙂

  • @RasmusSchultz

    @RasmusSchultz

    2 жыл бұрын

    By the way, immutable records and pure functions are a great way to side step all the debate over "who owns what" - every model object is validated at creation, mutations can't get anything into an invalid state, and every function is just a function, plain and simple. I've been using this approach on two TypeScript projects this past year or so, and it's remarkable how much of the nonsense and distractions we toil over in "Enterprise style" OOP architecture that just melts away. 😄

  • @pmo5821
    @pmo58212 жыл бұрын

    If the domain model isn’t handling the business logic, then it’s relying on something/someone outside to tell it how to do its own job and there’s no guarantee that these outside instructions are valid business-wise. Example: I want to reschedule a shipment. With a good domain model, it handles complexity like workdays, customer receiving days, capacity constraints. These are things that you don’t want someone else dictating to you *how* to handle.

  • @marko5734

    @marko5734

    4 ай бұрын

    More control at one place 👌

  • @neleus9238
    @neleus92382 жыл бұрын

    Thank you for the video, it reveals one of the most controversial topics. Having rich domain model is expensive because of existance of the second sibling, the persistence model which lives in database. Keeping them in sync is the biggest issue where ORM could help, but from my experience it solves the issue partially and introduces new issues. For that reason, I observe in the past 10 years more and more teams end up with a combination of 1) anemic model 2) pesistence model mapped directly (NoORM) to the former 3) transaction scripts. All three parts form together a complete domain model where none of three makes sense alone. It doesn't look DDD friendly though because our computation infrastructure introduces its restrictions to the way we can effectively design the domain model.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Yes, I'd say that's accurate. Not everything needs or gets value from an object model that exposes' behaviors and encapsulates business logic. Some are more CRUD in nature and with minimal logical nd use transaction scripts.

  • @RoughSubset
    @RoughSubset2 жыл бұрын

    Hi Derek, thanks for the very informative videos, what if you receive an order from an event but for the order to be idempotent there is a check to see if that order has been created before because the domain layer is not allowed to have any IO operations would that check still need to be done on the service/manager layer before passing the order to the aggregate root?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Define a unique constraint in your DB if applicable. Or use something like the reservation pattern if it's distributed kzread.info/dash/bejne/go6hkrSKd8bZY5s.html

  • @MsTArray
    @MsTArray2 жыл бұрын

    Hey Derek, What about domain events, should we trigger them inside the handler or the aggregate root / entity?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Wherever you're doing the state change ultimately. The event is represents why state was changed. If you're doing them within an aggregate, then there. If you're doing them in an transaction script, there.

  • @acap727
    @acap7272 жыл бұрын

    I've been doing Anemic domain model all this long! Now I know. I'm a fan of doing it like this though, otherwise, I'll need to make many factories and such. Maybe I just have not encountered significantly complex example so far.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Possibly. If consistency is hard to manage, that's a good indicator you have a lot of complexity.

  • @wely92
    @wely922 жыл бұрын

    I've been learning a lot on that topic recently, super interesting, any tips on a strategy to gradually migrate from anemic models to proper domain models in an app? (~15-20 microservices)

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Good topic idea!

  • @mehdihadeli
    @mehdihadeli2 жыл бұрын

    Thanks for this great video :) One question, Is it mandatory using repository in handlers with domain model approach and using directly our DbContext in our handlers in anemic domain model Or vise versa? I think this is just an example, and we could use both repository or directly using DbContext (vertical slice arch) in our handlers for both anemic and domain model approach. Thought?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Nothing is mandatory. I use a repository for I/O to get data from DB and build up an aggregate root. If you can accomplish that in another way, so be it. I'll often use the DBContext directly when working in more trx scripts for CRUD.

  • @mehdihadeli

    @mehdihadeli

    2 жыл бұрын

    @@CodeOpinion I think using repository is mostly in write side, for read part it is better we use dbcontext directly

  • @michaelstewart6358
    @michaelstewart6358 Жыл бұрын

    100% agree. But I would like to hear examples of what is considered complex enough to apply DDD patterns .

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    Hoping to create a video about that sooner rather than later.

  • @WillFuqua1987
    @WillFuqua19872 жыл бұрын

    Does a domain model imply mutation? I think that's a bit of sticking point. In the video's example, it is mutating the properties from within the domain model. If we all agree that mutation of state should _generally_ be avoided (which is a large, separate discussion), then what would a mutation-free domain model look like? Would the domain methods still live inside the domain model or would it begin to resemble the anemic pattern, where functions take in "domain POCOs" (for lack of a better term) and produce new versions of them?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I think it's more about data hiding than data mutation. I plan on coming out with a version in the future that takes a functional approach.

  • @ryanrobinson8682
    @ryanrobinson8682 Жыл бұрын

    The problem with the domain driven approach, as opposed to a more traditional service, is it doesn't scale well when you have: - Large monolithic legacy data schemas (big god object domain objects) How can it scale if you end up adding in hundreds of lines of logic and properties into a single class? - Entities/Models that have hard dependencies on other domain models and can't live in relative isolation.. - Does this conflict with composition over inheritance? Putting logic directly into models seems to promote more inheritance based solutions / abstract classes, rather than simple clean Interface abstractions (imo) Most companies I've seen with really terrible codebases, end up being that way due to developers throwing in more and more logic into the domain models, and it becomes a dumping ground of state. No-one seems to mention that this is one clear drawback from pure DDD, that when the design starts to go wrong, then it accelerates and goes wrong fast. You can have (and I prefer) anaemic domain models, but still structure the internals of your app to avoid duplication, or any other 'problem' that people seem to have with services/presenters. Those services and presenters still live in the domain assembly, they should just do one thing and do it well, in isolation. If that 'thing' is re-used by another controller for instance, then I don't see that being a big issue, it's not duplication to call into an abstraction, to perform some action that is needed. it's duplication when you copy and paste code that performs an action, into multiple places. Good developers wouldn't do that anyway. I think the whole argument for why anaemic isn't good and domain models is better, is a completely strawman argument.

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    I don't think it's a one or the other. I think it's context specific to which approach might make more sense. Building out entities/valueobjects/aggregates when all you end up having is trivial setter methods is pointless. Having large transaction scripts that call other transaction scrips or a ton of deeply complex logic isn't the answer either.

  • @marna_li
    @marna_li2 жыл бұрын

    I like to put as much of the domain logic in my Domain Objects (OOP-style). It is the most logical in OOP. There are cases when you put stuff in Services. But the Domain Objects should preferably contain their own rules, and perhaps expose them for services to use. I don't get the versioning problems of a true Domain Model. As long as the service represents something relatable, I have not problem. But logic in domain objects first. Services (services-first) usually end up much clunky and often contain code that has been copied with shared logic that has to be kept in sync. It just gets a mess if you, as a team, are not committed to keeping the structure. Just debugging and adding new stuff without understanding the whole. Services end up utility classes where you put stuff just by the name of that class. I have been in projects where stuff essentially are "hacks" added by clueless people like me.

  • @marna_li

    @marna_li

    2 жыл бұрын

    I did implement it at work: Clean Architecture and DDD with a true Domain Model. My reasoning was that an event-driven approach is easier to maintain with business requirements. This is after all the pattern I'm used to now. And the team backed it up. But the architects criticized us and we reverted everything into services because that was the pattern they'd decided for all services to use since they instead believed that that was easier to maintain for consistency reasons when people switch teams. And there was many more questions, like what about versioning. They said that they are not against experimenting but saw this effort as risky with such potentially big service. I doubt we will try it again though.

  • @adambickford8720
    @adambickford87202 жыл бұрын

    As long as there is 1 (and only 1) unambiguous owner of a business concept, and the codebase is consistent, I don't think it matters much. OOP and FP are almost complete opposites, yet both enjoy success.

  • @mikestock1848
    @mikestock1848 Жыл бұрын

    Can anyone explain to me how a rich domain model is any different to an anemic style model In the anemic model we group our shared functionality by folder In the rich domain model you group it in one file I don't see a difference or the benefit of doing a rich domain model over anemic, especially when you have layers of complexity and relationships I've seen many people do rich domain modelling really really badly, so it may be good if its done right, but doing it right is very very difficult. It's very easy to do the anemic version and very easy to fix it if it goes wrong I've also found rich domain models extremely rigid to changes Finally if you start changing the implementation, if everything is in a rich domain model it keeps sucking in more and more logic into it, making it more and more complicated to understand, in the anemic version you can just create a different implementation and use dependency injection. Isn't the point of classes just to structure things into logical places? On your file system we use a folder for that. The problem with the rich domain model is you have to really understand what you are doing in order to keep that design on track, it can very quickly spiral out of control. If it does spiral it goes very very bad, because only the rich domain model has the knowledge to do certain work and it will naturally to the untrained eye keep puilling in more and more functionality. Now maybe that isn't a flaw in the rich domain model, its a flaw in us, but something that is so hard to get right, the pay off has to be worth it and I just don't think it is.

  • @tullochgorum6323
    @tullochgorum6323 Жыл бұрын

    As you say, the value of the POCO/POJO data bucket is highly situational, and it's absurd to be dogmatic that it's an anti-pattern. I'm currently writing a trading application that injects pluggable modules into a well-defined pipeline of steps. The early steps build up the data required for decision making, and the later steps determine and execute the actions. All these steps operate on the same data and may use it in innovative ways that the developer can't anticipate. In this scenario it seems perfectly sensible to have a passive bucket of data that is passed from step to step, with a central transactional script coordinating the action. It's simple, readable, easy to change and efficient to execute in a world where speed matters. Why use something complex, just because it's seen as fashionable and cool, when something simple and unfashionable does the job better?

  • @olmanmora21
    @olmanmora212 жыл бұрын

    Even though the first example the methods don't actually have any logic they are semantically and cognitively better than just have your transaction script handling those properties on its own, and also makes easier to attach new functionality to it without impacting the consumer (Minimum YAGNI damage)

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Just like transaction scripts, there's a line that gets crossed slowly by adding more and more logic. It's being aware of when you are about to cross that line.

  • @tomheijtink8688
    @tomheijtink8688 Жыл бұрын

    There is something wrong with the statement about complexity that I’ve not yet been able to put my finger on. But it sounds off. I’ve watched your video on complexity attempting to sort of quantify it. But all it showed me was confirming what I’m thinking about a lot. In software development complexity seems to be the rule rather than the exception. Even my most simple projects that I do become complex really fast. And I’m talking about business complexity. Not technologically. To then first go for an anemic approach to then have to rewrite everything to a rich approach seems like a waste of time. Even a simple todo app has complex business logic. Because no one wants just a simple app. Sure maybe at the start. But then all these feature requests come in. Returning todo’s, sharing todo’s. Todo’s based on location, day of week or time of day. Etc. Plus. I’m really wondering what the extra cost is of DDD and a modular monolith or a distributed system. Once you have experience with it, great tooling. A template which you can quickly generate. Packages and utilities. It’s all rather simple to setup and start programming on the domain in no time. Each domain has their own challenges and complexity.

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    Core of your domain generally will be complex. But in my experience, supporting boundaries generally are less complex if not boring. That's because it's not the focus, and it's there purely in a supporting role.

  • @tomheijtink8688

    @tomheijtink8688

    Жыл бұрын

    @@CodeOpinion that’s true. In “simple” apps there might not be a lot of need for supporting domains. I’m sorry if I missed that point. But it makes sense in hindsight. The more interactions between the boundaries make an application way more complex than if the boundaries can sort of operate on their own.

  • @clarencemanuel7902
    @clarencemanuel79022 жыл бұрын

    Some context need a rich domain, some don't, for those that don't (usually very CRUDdy ones), an anemic domain is perfectly fine.

  • @lluism200
    @lluism200 Жыл бұрын

    At which point do you consider the "anemic model" stops being anemic? I've been using the service-transaction scripts for a while, 99% of the time it feels the issues you want to tackle are not complex enough to build an entire rich domain around them. But I still place some logic in the data models. Mainly basic stuff to encapsulate some privates, maybe a validation or two, likew your example. where is the line drawn where a model is not anemic anymore?

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    Check out this video where I talk about complexity: kzread.info/dash/bejne/fmWa0aiiodLWecY.html

  • @bunnihilator
    @bunnihilator2 жыл бұрын

    EntityService is not compliant with Single Responsability Principle from SOLID. Because people can put anything in there. Can you make a video about bounded context dependency - upstream downstream dependency (downstream can call upstream classes right?)

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    So direction of dependencies eg, Clean? I've talked about it before but ya I can hit on it in a future video.

  • @bunnihilator

    @bunnihilator

    2 жыл бұрын

    @@CodeOpinion No. I mean the concept of upstream/downstream dependency in DDD. Which states that changes in the upstream means that the downstream is the one that needs to adapt to it. Upstream can't change if downstream changes. For example when you interface with a payment gateway, for ex. stripe, if stripe changes its api you are do one who needs to adapt to stripe's changes. So in that relationship stripe would be the upstream. This can occur between your bounded contexts.

  • @vijayjayaram606
    @vijayjayaram6062 жыл бұрын

    I am so sorry I might have to watch this again n again to understand 🙏

  • @robinjl1
    @robinjl1 Жыл бұрын

    🤔hmm, I heard two different things here. I first heard you should use anemic models situationally (depending on your intent). But then the conclusion indicated you should start with a transaction script where low complexity and as complexity grows, consider moving to a domain model (with no suggestion of considering an anemic model).

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    What most people view as an anemic domain model really are generally transaction scripts with look alike aggregates. Just don't create an aggregate (object model) with no behavior. Just use data models in your transaction scripts.

  • @chswin
    @chswin Жыл бұрын

    I use this pattern in my web api almost exclusively

  • @tecTitus
    @tecTitus3 ай бұрын

    Anemic model + business logic for rules and mutations. BL + CRUD, Complexity is under control, same architecture for everything. Workd more than fine for 7 years.. See no reason to ever change it. If interoperations between two enitites, it's BL class pulls in the needed sub BLs. And Built it up like that. Edit: There's only one overwritten savechanges in the whole code, above all BLs, multiple changes to unlimied enities. To avoid using transaction.

  • @superrebotar
    @superrebotar2 жыл бұрын

    Man I wish i had discovered your channel before. Now i don't know how to watch all your videos

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    There are enough videos at this point that you'll be watching for awhile :)

  • @GreatSot9629
    @GreatSot9629 Жыл бұрын

    what is anemic domain model?

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    What you think is a rich domain model but contains no behavior and is only data.

  • @charliedeuter946
    @charliedeuter9464 ай бұрын

    The 'anemic domain model' idea is just a misunderstanding of the domain model by OOP folks. The domain model just means having a domain layer, it's completely unrelated to how you set it up, as oop, procedural, or functional.

  • @drkl9066
    @drkl90662 жыл бұрын

    Man, I dont know you, but I think u should write a book. Just saying. Thanks so much for sharing your knowledge. I'm trying to learn OOP and I'm building an api exactly like your example, and I have an anemic entity User and I feel thats like a DTO or something like that. Ps. I'm learning english too, it's not a translation. Sorry for my mistakes.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Hopefully the videos help!

  • @drkl9066

    @drkl9066

    2 жыл бұрын

    @@CodeOpinion I'm sure they will help.

  • @mlntdrv
    @mlntdrv Жыл бұрын

    Can't stop hearing SHITMAN! :D Transaction scripts and anemic models are only OK in 1% of the time when you do something really simple. The moment you get some complexity (2 ifs maybe) you need a domain model and that's 99% of the time.

  • @RasmusSchultz
    @RasmusSchultz Жыл бұрын

    You say "you have no domain model", are you being hyperbolic here? From where I'm looking, there is a domain model - it's just not very object oriented, it's more just records and functions. I've built a couple of Typescript projects using immutable records and pure functions - it's in many ways a much better domain model than the typical object oriented approach with entities and object orientation. I don't think the term domain model implies any specific patterns or paradigm? I don't know if formal DDD might have a stricter definition, but "domain" and "model" certainly were concepts we used and talked about long before DDD.

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    A bit yes. In OO land, a domain model is often really meaning a class that encapsulates data and exposes behavior. Doing a more procedural approach as I explained is reasonable as I mentioned. But as mentioned in a more functional manner, you'd be using types more to enforce validity as I mentioned in my recent video about guard clauses.

  • @lucasterable
    @lucasterable9 ай бұрын

    Anemic model os OK for reads.

  • @Karg537
    @Karg537 Жыл бұрын

    Prefer anemic- ish than a fat model. It makes code hard to refactor, trace abd understand.

  • @CodeOpinion

    @CodeOpinion

    Жыл бұрын

    Thanks for the comment. I'm making an assumption on what you mean by "fat model", but that is a good topic for another video actually. Often times people create object models that are based on relationships rather than them being a consistency boundary. This is why I think most end up "fat". If your creating an aggregate driven by the fact it's a consistency boundary, it won't be fat it will be pretty slim and focused.

  • @victortodoran1828
    @victortodoran18282 жыл бұрын

    I'm sorry but I found no value in this video and I watched twice. There is a whole world between cramming entities with logic and transaction scripts. A world full of Validators, Calculators, Mappers, Total Collectors, Encryptors and a lot of testable and reusable components. The most popular arguments for cramming entities with logic seem religious in nature. Ex: because it's how oop is supposed to be implemented or to have a healthy domain model. I'm writing software for a while now and have yet to see an app with entities crammed with logic that is doing well.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    I get it, we've all had our own experiences that shape our view. It's hard to provide an example of true complexity that I can really illustrate in a video. If I did, nobody would watch it because they would be thinking "I don't understand any of this example". I talked about this same example in another video about using invariants and a domain model. kzread.info/dash/bejne/aGiiybJmkbi_gMY.html

  • @mikestock1848

    @mikestock1848

    Жыл бұрын

    Another thing is you can then as your team invent your own language, Service is fine as a name if everyone understands what the word means Builders/Mappers -> Build things Service -> Controls flow Encryptors -> Encrypt things

Келесі