域对象,POCO和实体之间有什么区别?


81

我对他们的印象基本相同。模型对象也一样吗?

现在,在我的体系结构中,我有:

class Person 
{

    public string PersonId;        
    public string Name;
    public string Email;

    public static bool IsValidName() { /* logic here */ }
    public static bool IsValidEmail() { /* logic here */ }
}


class PersonService
{
    private PersonRepository pRepository;

    PersonService()
    {
        pRepository = new PersonRepository();
    }

    public bool IsExistingEmail(string email)
    {
        //calls repo method to see if email is in db
    }


    public Person GetPerson(email)
    {
        return pRepository.Get(email);
    }


    public void SavePerson(Person p)
    {
        if (Person.IsValidEmail(p.Email) && !IsExistingEmail(p.Email)
        {
            pRepository.Save(p);
        }
    }

}


class PersonRepository
{
    public void Save(Person p)
    {
        //save to db
    }

    public Person Get(string email)
    {
        //get from db
    }

    public bool IsExistingEmail(string email)
    {
        //see if email in db
    }

}

所以这上面的类都是POCODomain ObjectModel objectentity

Answers:


115

我(非标准)Layman定义

  • POCO-普通的旧%Insert_Your_Language%对象。没有逻辑的类型。它只是将数据存储在内存中。您通常会在其中看到自动属性,有时还会看到字段和构造函数。
  • Domain object与您的域相关的类的实例。我可能会从域对象中排除任何附属对象或实用程序对象,例如,在大多数情况下,域对象不包括日志记录,格式化,序列化,加密等内容-除非您专门构建要分别记录,序列化,格式化或加密的产品。
  • Model object我认为是一样的Domain object。人们倾向于将其互换使用(我可能是错的)
  • Entity 一个有 id
  • Repository一类,它从一侧(例如数据库,数据服务或ORM)与数据存储以及服务,UI,业务层或任何其他请求主体进行通信。它通常隐藏所有与数据相关的内容(例如复制,连接池,键约束,事务等),并使处理数据变得简单
  • Service通常通过公共API提供某些功能的软件。取决于层,它可以是例如RESTful自包含容器,或者是允许您查找所需类型的特定实例的类。

原始答案

这些是(分布式)域驱动设计中大量使用的术语。他们不一样。术语模型对象可用作领域对象的同义词。

域对象。业务特定区域中的对象表示对领域专家有意义的内容。域对象主要由实体和值对象表示。一般而言,大多数生活在领域层中的对象都对模型有所贡献,并且都是领域对象。

实体。从根本上说,对象不是由其属性定义的,而是由连续性和标识性的线程定义的。(意味着它必须具有ID

POCO。一个没有复杂逻辑的简单对象,通常只有几个属性,可与ORM一起使用或用作数据传输对象

class Person-实体和POCO,此类的实例是域对象
class PersonService-服务
class PersonRepository-存储库


4
请参阅上面的代码示例,让我知道您将如何应用这些条款。
jpshook 2011年

好答案。我已经准备好回答这个问题,但这将是您答案的副本。我可以补充一点,除了实体和值对象之外,您还具有域事件等。所有对象以及位于模型层中并为模型做出贡献的都是域对象。
Magnus Backeus 2011年

1
如果不需要识别POCO,那么ORM可以如何加载它。那不合逻辑!
帕斯卡

1
为什么这种公然的虚假信息被最强烈地接受和接受。POJO不是没有逻辑的类型。实际上,Martin Fowler专门创造了术语POJO来与Entity Bean形成对比(“我们指出了将业务逻辑编码为常规Java对象而不是使用Entity Bean的许多好处”。martinfowler.com/bliki/POJO.html
该用户需要帮助

1
很抱歉,如果我的评论措辞过硬,但是再次提醒您,当术语的创造者将POJO定义为明确包含业务逻辑时,您的个人经历并不重要。实际上,他会根据您认为是反模式的贫血领域模型(martinfowler.com/bliki/AnemicDomainModel.html)对您的实践进行分类,他建议您改用POJO。无论是反模式是出于这个定义的范围,但有一点是明确的:POJO并没有意味着没有任何业务逻辑的对象。
该用户需要帮助

18

它更多地是功能的内涵。域对象是特定于您的逻辑实现的对象,它可能比简单的POCO更复杂;实体具有表示某种东西的含义(通常是指持久性介质),而POCO只是类的快速标识符。模型只是一个用来表示对象的术语(通常包含状态,通常与UI或DB打交道)。

并不是说功能上有任何区别,它们只是用来更紧密地描述事物的不同术语。就像赛车,卡车和家庭轿车之间的区别一样。都是汽车,但每个术语都更具描述性。


我更新了代码示例,可以发表评论吗?我只想确保在提问时使用正确的术语。
jpshook

18

基本上可以归结为内部逻辑

  1. 域对象具有内部域逻辑,用于进行验证等操作。
  2. 模型基本上是一个轻量级的Domain对象,他们知道所拥有的数据,但对如何使用它一无所知
  3. 实体保存数据,并对数据来自何处以及将在何处保存,更新等有一些内部了解。
  4. POCO拥有数据并可能具有一些关于自身的内部知识,例如财产集合中所有物品的总价值是多少
  5. DTO是最简单的一项,它只保存数据,没有逻辑

它们基本上都用于同一件事,这就是您希望它们变得多么聪明

根据您的代码示例,Person类将是域对象或模型,其他两个是服务和存储库。域对象,Pocos,模型,dto等都像消息一样使用,从一层传递到下一层,服务类(如PersonService)是应用程序中的一层,与存储库类(如PersonRepository)相同。要获得良好的概览,请访问http://bob-the-janitor.blogspot.com/2009/07/n-tier-design-revisit-part-1-over-view.html,在这种情况下,它是关于使用基本上是dto的数据实体


11

上面的答案中已经有关于Domain和Model的很好的解释。

在数据库上下文中,实体是指实体关系模型ERD中的项目。(即表格中的一行)

Microsoft-Dotnet-EntityFramework-World中,实体是指可以使用Data(Base)Context从数据库加载并保存到数据库的对象。通常,没有其Data(Base)Context实体就无法存在。(单元)很难测试这些类的业务功能。

Pocos(普通的旧CommonRuntime对象)可以不使用PersistenceFramework(EntityFramework或NHibernate)而存在,因此它们很容易测试。

poco一词是出于同样原因在Java世界中创建的pojo(普通的旧Java对象)的变体


拒绝投票的理由是什么?问题是“域对象,POCO和实体之间有什么区别?” 我解释了Entity和Poco之间的区别
k3b

“上面的答案中已经有关于域和模型的很好的解释。” 如何选择依赖于其他答案的答案作为有效答案?
2011年

np。回想一下,我应该发表评论,要求您提供完整的答案。下次会考虑2倍。
jpshook

3

域对象是应用程序域层中的一个实体,例如。地址类。“模型”的含义相同-“域模型”中的实体。

POCO(普通的旧CLR对象)是没有定义行为(方法)的对象,仅包含数据(属性)。POCO通常用作DTO(数据传输对象)以在层之间承载数据,然后通常将数据用于填充域对象/实体。


POCO不能是实体吗?我以为POCO可以有行为,但必须对持久性一无所知?
jpshook 2011年

@Developer是的,您的域模型/实体确实可以是POCO的-这就是所谓的“贫血”域模型-请参阅martinfowler.com/bliki/AnemicDomainModel.html
MattDavey

您如何看待这种贫血?您如何定义“富域对象”?如果域对象不能直接或间接与数据库交互,它们将具有什么样的丰富功能?
jpshook

@Developer我认为由POCO对象组成的域模型是贫乏的,因为传统上POCO类没有任何丰富的功能,只有数据。遵循关注点分离原则(en.wikipedia.org/wiki/Separation_of_concerns),域模型中的对象完全不应该与数据库访问有关(因此流行的术语“持久性无知”)。领域模型中的实体应具有的功能是业务逻辑-它们应捕获并封装所代表的问题/领域的逻辑规则和工作流。
MattDavey 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.