我是不是正确使用域对象?

Posted

技术标签:

【中文标题】我是不是正确使用域对象?【英文标题】:Am I using Domain Object correctly?我是否正确使用域对象? 【发布时间】:2016-04-09 18:48:23 【问题描述】:

据本文here

您可以将它们 [Services] 视为“更高级别的域对象”,但服务不是业务逻辑,而是负责域对象和映射器之间的交互。这些结构最终创建了一个“公共”接口,用于与域业务逻辑进行交互。您可以避免它们,但代价是会将一些域逻辑泄漏到控制器中。

我一直在阅读 MVC,并将 M 部分拆分为服务、域对象和数据映射器。服务和数据映射器很容易弄清楚,但我不明白域对象的原因,你能给我一些例子吗?这是我的代码:

会员服务

class MemberService extends Service

    public function authenticate()
    
        $domainObject = $this->domainObjectFactory->getDomainObject('Member');
        $dataMapper = $this->databaseFactory->getMapper('Member');  

        $_temp_sess_id = 0;
        $_temp_sess_password = "";

        $member = $dataMapper->fetch( $_temp_sess_id );
        $authenticationResult = $domainObject->checkPassword( $member['password'], $_temp_sess_password );

        if (!$authenticationResult)
        
            $member = ['user_id' => 0];
        

        return $member;
    

成员域对象

class MemberDomainObject extends DomainObject

    public function checkPassword( $dataMapperPassword, $locallyStoredPassword )
    
        if ( $dataMapperPassword !== $locallyStoredPassword )
            return false;
        return true;
    
     

更新:

这个问题是关于方法 checkPassword 以及为什么需要创建一个单独的对象只是为了使用可以在服务内部使用的 IF 语句,从而节省 RAM 使用额外资源来创建新对象。

【问题讨论】:

Understanding domain objects/services的可能重复 好吧,它说:“域对象是数据,域服务是数据部分。”。所以我必须在服务部分执行所有 if,同时将 $member 存储在 DO 中? 另外,根据这里的答案:***.com/questions/5863870/…,“您可以将它们 [Services] 视为“更高级别的域对象”,但服务负责域之间的交互而不是业务逻辑对象和映射器。” 【参考方案1】:

您刚刚通过示例中的某个工厂创建了 MemberDomainObject。为此目的,您显示的代码没有或为零的信息价值。

你需要制作一个真正的应用程序,至少包含很少的对象、服务和两个域,所以任何人都可以说“你很好地使用了域对象”。

您不只对“模型对象”感兴趣吗?如果您需要确定正确的“服务>工厂>模型对象>映射器”关系使用,则无需谈论域对象。


通过工厂创建对象是一种很好的做法,因为您可以在重构期间在一个地方更改或添加构造函数调用。

一个建议是:在你的工厂中使用带有命名空间 (FQN) 的类名,它可以帮助你浏览代码并进行重构

$member = $this->domainObjectFactory->getDomainObject(MemberDomainObject::class); //in php5.5+

你可以用

代替
class DomainObject


   static function className()
      return get_called_class();
   


$member = $this->domainObjectFactory->getDomainObject(MemberDomainObject::className());

在 php

$member = $this->domainObjectFactory->getMember();

不是问题,因为您可以在 ::getMember() 中指定返回类型

【讨论】:

我无法弄清楚命名空间。另外,你写的东西是对的,但它没有回答我的问题。我的问题是 - 为什么我需要域对象?如果你看这一行: $authenticationResult = $domainObject->checkPassword( $member['password'], $_temp_sess_password );这可以用一个简单的 IF 语句代替,这样就无需使用 RAM 资源来创建新对象。 如果您有兴趣,请将您的问题更改为“为什么要将模型逻辑保留在模型中而不是控制器中”之类的内容...... 我问的方式是完全有效的伴侣。 那我的回答也是有效的,很高兴帮助:) 不,你的回答根本没有回答我的问题。你只是告诉我使用命名空间,并重写域对象的创建/获取,最终得到相同的结果。我的问题是关于 checkPassword 方法。为什么甚至有必要为该操作创建一个单独的对象。

以上是关于我是不是正确使用域对象?的主要内容,如果未能解决你的问题,请参考以下文章

验证篇(7.0) 05. SSL安全隧道用域帐户验证 ❀ 飞塔 (Fortinet) 防火墙

公司电脑加了域,用域账户登录之后,office outlook 2007就无法正常使用。

苹果电脑无法用普通域用户加入域,用域管理员却可以,怎么破!?

js数组,对象,作用域

使用java流将两个相同大小(和不同类型)的列表组合到域对象列表中

画作用域链的原则