问题描述
我想知道使用贫血域模型的利弊是什么(请参见下面的链接).
推荐答案
专业人士:
- 您可以声称这是一个域模型 并吹嘘您的开发人员朋友 并将其放在您的简历上.
- 很容易自动生成 从数据库表.
- 它映射到数据传输对象 出人意料的很好.
缺点:
- 您的域逻辑存在于某个地方 否则,可能在一个班上 类(静态)方法.或你的gui 代码.或在多个位置,都具有冲突的逻辑.
- 这是一个反模式,所以其他 开发人员会问您是否 了解对象的概念 定向设计.
其他推荐答案
具有"贫血域模型"为反图案,为什么有如此多的系统实现?
我认为有几个原因
1.系统的复杂性
在一个简单的系统中(几乎是您在Internet上找到的所有示例和示例代码),如果我想实现:
将产品添加到订单
我将此功能放在订单上
public void Order.AddOrderLine(Product product) { OrderLines.Add(new OrderLine(product)); }
良好和超级对象的方向.
现在,假设我需要确保我需要验证该产品存在于库存中,并在不存在的情况下抛出异常.
我不再真正将其订购,因为我不希望我的订单依赖库存,所以现在需要继续使用服务
public void OrderService.AddOrderLine(Order order, Product product) { if (!InventoryService.Has(product) throw new AddProductException order.AddOrderLine(product); }
我也可以将iInventoryService传递到order.addorderline,这是另一种选择,但这仍然使订单依赖于contingoryservice.
顺序仍然有一些功能.addorderline,但通常仅限于订单范围,而根据我的经验,有更多的业务逻辑过时范围.
当系统更重要的是基本的crud时,您最终将以订单服务获得大多数逻辑.
2.开发人员对OOP的看法
互联网上有很多关于逻辑应在实体上进行的加热讨论.
之类的东西
order.save
订单应该知道如何保存自己吗?假设我们有一个存储库.
现在可以订购订单行?如果我尝试使用简单的英语来理解它,那也没有真正的意义.用户将产品添加到订单,所以我们应该执行user.addorderlinetoorder()吗?这似乎是过分的.
orderService.addorderline()怎么样.现在有点有意义!
我对OOP的理解是,对于封装,您将功能放在函数需要访问类内部状态的类上.如果我需要访问Order.orderlines Collection,我将订单订单addorderline()放在订单上.这种方式课程的内部状态不会暴露.
3. IOC容器
使用IOC容器的系统通常是完全贫血的.
这是因为您可以测试具有接口的服务/存储库,但不能测试域对象(轻松),除非您在所有界面上放置接口.
由于" IOC"目前被称为解决所有编程问题的解决方案,因此许多人盲目遵循它,这种方式最终以贫血的域名模型.
4. OOP很难,程序很容易
我有一点" 知识的诅咒在这方面,但我发现了 对于拥有DTO和服务的新开发人员来说,比丰富的领域要容易得多.
可能是因为有了丰富的领域,很难知道要在哪个类中放置逻辑.什么时候创建新类?要使用哪些模式?等等..
使用无状态服务,您只需将其拍在最接近名称的服务中.
其他推荐答案
之后,我脑海中已经有一个想法了很长时间了.我相信" OOP"一词具有并非真正意图的含义.众所周知,Anagram的意思是"面向对象的编程".当然,重点是"定向"一词.它不是" OMP",意思是"对象强制编程". ADM和RDM都是OOP的示例.他们利用对象,属性,方法接口等.但是,ADM和RDM之间存在区别,我们选择封装事物.他们是两个不同的东西.说ADM是不好的OOP并不是一个准确的陈述.也许我们需要不同的术语来封装的量级.此外,我从不喜欢反图案一词.它通常由对方群体的成员分配给某事. ADM和RDM都是有效的模式,它们简单地考虑了不同的目标,并旨在解决不同的业务需求.我们当中那些执业DDD的人至少应该欣赏这一点,而不是通过抨击那些选择实施ADM的人来降低他人的水平.只是我的想法.
问题描述
I would like to know what the pros and cons are for using an Anemic Domain Model (see link below).
推荐答案
The pros:
- You can claim it's a domain model and brag to your developer friends and put it on your resume.
- It's easy to generate automagically from database tables.
- It maps to Data Transfer Objects surprisingly well.
The cons:
- Your domain logic exists somewhere else, probably in a class full of class(static) methods. Or your GUI code. Or in multiple places, all with conflicting logic.
- It's an anti-pattern, so other developers will ask if you understand the concepts of object oriented design.
其他推荐答案
With "Anemic Domain Model" being anti-pattern, why are there so many systems that implement this?
I think there are several reasons
1. Complexity of the system
In a simple system (which is almost all the examples and sample code you find on internet) if I want to implement:
Adding product to Order
I put this function on the Order
public void Order.AddOrderLine(Product product) { OrderLines.Add(new OrderLine(product)); }
Nice and super object oriented.
Now let's say that I need to make sure that I need to validate that the product exists in inventory and throw exception if it doesn't.
I can't really put it on Order any longer, since I don't want my order to be dependent on Inventory, so now it needs to go on the service
public void OrderService.AddOrderLine(Order order, Product product) { if (!InventoryService.Has(product) throw new AddProductException order.AddOrderLine(product); }
I could also pass IInventoryService to Order.AddOrderLine, which is another option, but that still makes Order dependent on InventoryService.
There is still some functionality in Order.AddOrderLine, but usually it is limited to Order scope, while in my experience there is a lot more Business Logic out of Order scope.
When the system is more then just basic CRUD, you will end up with most of your logic in OrderService and very little in Order.
2. Developer's view of OOP
There are a lot of heated discussions on the internet about which logic should go on entities.
Something like
Order.Save
Should Order know how to save itself or not? Let's say we have repositories for that.
Now can Order add order lines? If I try to make sense of it using simple English, it doesn't really make sense either. User adds Product to Order, so should we do User.AddOrderLineToOrder()? That seems like overkill.
How about OrderService.AddOrderLine(). Now it kinda makes sense!
My understanding of OOP is that for encapsulation you put functions on classes where the function will need to access class's internal state. If I need to access Order.OrderLines collection, I put Order.AddOrderLine() on Order. This way class's internal state doesn't get exposed.
3. IoC Containers
Systems that use IoC containers are usually fully anemic.
It is because you can test your services/repositories which have interfaces, but can't test domain objects (easily), unless you put interfaces on all of them.
Since "IoC" is currently lauded as solution for all your programming problems, a lot of people blindly follow it and this way end up with Anemic Domain Models.
4. OOP is hard, procedural is easy
I have a bit of a "Curse of Knowledge" on this one, but I have discovered that for newer developers having DTOs and Services is a lot easier than Rich Domain.
Possibly it is because with Rich Domain it is more difficult to know on which classes to put the logic. When to create new classes? Which patterns to use? etc..
With stateless services you just slap it in the service with closest name.
其他推荐答案
Following this, there has been a thought in my head for a very long time now. It is my belief that the term "OOP" has taken on a meaning not truly intended for it. The anagram mean "object oriented programming", as we all well know. The focus of course is on the word "oriented". It isn't "OMP", meaning "object mandated programming". Both ADM and RDM are examples of OOP. They make use of object, properties, methods interfaces and so forth. However, there is a difference between ADM and RDM in how we choose to encapulate things. They are two different things. To say that ADM is bad OOP is not an accurate statement. Maybe we need different terms for vaious levels of encapsulation instead. In addition, I never liked the term anti-pattern. It is usually assigned to something by members of an opposing group. Both ADM and RDM are valid pattern, they simple have different goals in mind, and are intended to solve different business needs. Those of us who practice DDD should, at the very least, appreciate this, and not fall to the level of others by bashing those who choose to implement ADM. Just my thoughts.