将域实体的可变属性存储为值对象是否可以? [英] Is it okay to store a domain entity's mutable properties as a value object?

查看:27
本文介绍了将域实体的可变属性存储为值对象是否可以?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够更改和传递我的 UserEntity 的某些部分,并且某些部分应该保持不变.

There are certain parts of my UserEntity that I would like to be able to change and pass around, and there are certain parts that should remain constant.

例如,我从不想更改我的 UserEntity 的 id,但电子邮件或密码等内容可能经常更改,并且也可以被 UserEntity 之外的其他对象使用.

For example, I NEVER want to change my UserEntity's id, but things like email or password may change often, and can be used by other objects outside of the UserEntity as well.

这样的一个实例是在创建 UserEntity 时.由于 UserEntity 在没有 id 的情况下无法存在,因此我的控制器可以创建一个 UserData 对象来标准化 UserEntity 属性.映射器在数据库中创建实体后,它会创建一个新的 UserEntity 并在构造函数中传入 id 和 UserData 对象.

One instance of this would be when creating a UserEntity. Since a UserEntity cannot exist without an id, my controller could create a UserData object that would standardize the UserEntity properties. After the mapper creates an entity in the db, it would create a new UserEntity and pass in the id and UserData object in the constructor.

当 UserEntity 需要电子邮件或密码等信息时,它可以只查看其 UserData.

When UserEntity needs info like email or password, it can just look at its UserData.

看起来更便携,但这是否过大了?有没有更好的解决方案?

Seems more portable, but is this overkill? Is there a better solution?

注意

  • 我认为这可能是好的原因:可变字段的值需要标准化……有时这些字段需要在实体本身之外传递.例如,在创建实体之前.通过创建一个可以传递的值对象,我们提供了一个标准化的点来从任何地方分配这些值,以及可以在实体外部传递的东西.

  • The reason why I think this might be good: the values of the mutable fields need to be standardized...and sometimes these fields need to be passed around outside of the entity itself. For example, before the entity has been created. By created a value object that can be passed around we provide a standardized spot to assign these values from anywhere, as well as something that can be passed around outside of the entity.

标准化"是指我的信息需要统一,无论它存在于何处.例如,email 必须始终为 n 长度并且在有效格式中,name 始终需要为 n长度等.我的目标是我希望能够在一个位置设置这些规则"......并且由于 UserEntity 的这些属性(可变属性)存在于实体本身之外,有时,他们有可能独自生活在自己的价值对象中.

By "standardize" I mean that my information needs to be uniform, wherever it exists. For example, email needs to always be n length and in a valid format, name always needs to be n length, etc. My goal here is that I'd like to be able to set those "rules" in a single spot...and since these properties of the UserEntity (the mutable ones) exist outside of the entity itself, sometimes, they could potentially live on their own, in their own value object.

推荐答案

我不认为有一种真正的方法"可以做到(无论你读到什么)...模型,那么对我来说听起来不错.当您说其中许多字段需要标准化"以及为什么不能作为 UserEntity 的一部分来完成时,我不确定您的确切含义,但无论如何.也就是说,您很可能可以在没有完全独立的对象类的情况下完成您想要做的事情.

I don't think there is "one true way" to do it (no matter what you read about it)... if it makes sense in your model, then it sounds good to me. I'm not sure exactly what you mean when you say "many of those fields need to be standardized" and why that couldn't be done as part of the UserEntity, but whatever. That said, odds are you can accomplish exactly what you're trying to do without an entirely separate object class.

评论/批评:

您的建议与严格的对象"模型并不真正相符,即 UserData 只是由真正属于 UserEntity 属性的事物组成,并且与这些属性没有其他潜在关系.

What you are suggesting doesn't really go along with a strict "object" model, i.e. the UserData is just made up of things that are really attributes of UserEntity, and there's no other underlying relationship to those attributes.

我不太确定为什么你需要一个单独的对象在实体之外传递......如果你需要数据,为什么你不能只传递 UserEntity 并从那里访问它?在将数据传递给 UserEntity 构造函数之前,您需要对数据进行哪些处理,而通过将数据收集到 stdClass 实例中然后在 UserEntity 中处理它无法轻松完成?

I'm not really sure why you would need a separate object to pass around outside the entity... if you need the data, why can't you just pass around the UserEntity and access it from there? What do you need to do with the data before passing it to the UserEntity constructor that couldn't just as easily be accomplished with gathering the data together in an instance of stdClass and then processing it in UserEntity?

如果是我,我会做以下类似的事情(例如,创建一个新用户):

If it were me, I'd do something more like the following (for, say, creating a new user):

<?
// assume an appropriately defined UserEntity class...

// I'm using stdClass just to keep the parameters together to pass all at once
// I'm assuming some basic user data passed from the browser
$user_data = (object) array(
    'email' => $_REQUEST['email'],
    'name' => $_REQUEST['name'],
    'password' => $_REQUEST['password'],
    'confirm_password' => $_REQUEST['confirm_password']
);

/*
validateData is static so it can be called before you create the new user
It takes the $user_data object to validate and, if necessary, modify fields.
It also takes a $create flag which indicates whether the data should be
checked to make sure all of the necessary fields are there to create the user
with.  This allows you to call it on update with the $create flag unset and it
will pass validation even if it's missing otherwise required fields.
It returns $result, which indicates pass or failure, and the potentially modified
$user_data object
*/
$create = TRUE;
list($result, $user_data) = UserEntity::validateData($user_data, $create);

// equivalence allows you to pass back descriptive error messages
if ($result === TRUE) {
    // create the user in the database, get back $user_id...
    $user = new UserEntity($user_id, $user_data);
}
else {
    // return error to user
}

// access user data either individually, or if you want just make a getter
// for the entire group of data, so you can use it just like you would a
// separate UserData object
send_double_opt_in($user->getUserData());
?>

<小时>

编辑以解决提供的更多信息:


Edit to address more information provided:

您说这些属性存在于 UserEntity 之外,并且它们可能独立存在...您的意思是这些属性可以在不打算用于 UserEntity 对象的情况下被收集、使用和丢弃吗?如果是这种情况,那么单独的对象将完全适合该数据.如果不是,如果数据总是从属于现有的或未来的 UserEntity,那么这些属性将永远不会独立存在"……让我们称之为全局数据"的观点.当您将整个系统视为一个整体,而不仅仅是时时的代码时,数据很可能属于"UserEntity 类.

You say these properties exist outside of the UserEntity, and they could potentially live on their own... Do you mean that these properties could be gathered, used, and discarded without even being intended for a UserEntity object? If that's the case, then a separate object would be entirely appropriate for that data. If not, if the data is always subordinate to either an existing or future UserEntity, then those properties will never "live on their own" from a... let's call it a "global data" point of view. When you consider the entire system as a whole, not just the code from moment to moment, it's likely that the data "belongs to" the UserEntity class.

至于静态方法,我认为没有特别的理由要避免它们(显然),但每个人都有自己的理由.许多其他架构会稍微复杂一些,但这里有一些选项:

As for static methods, I see no particular reason to avoid them (obviously), but to each his own. Many other architectures would be a little more complex, but here are some options:

  1. 在构造函数中验证数据.问题是,如果它没有验证,您将不得不删除数据库条目.丑.
  2. 将数据库交互以及数据验证移到构造函数中.这可能会违反您首选的对象模型,您只需在创建对象后检查其状态(即设置公共属性 $this->status = 'error'; 或其他内容)就像告诉你发生了不好的事情,你必须处理).
  3. 创建一个独立的函数来验证数据.丑陋,因为这是一个专门与 UserEntity 和/或其数据相关的函数.
  4. 或者,按照您的建议创建一个单独的 UserData 对象并完成它.与第 2 步非常相似,您必须拥有某种 $status 属性来指示验证失败.
  1. Validate the data in the constructor. The problem is that if it doesn't validate, you'll have to remove the database entry. Ugly.
  2. Move database interaction into the constructor, along with data validation. This could violate your preferred object model, and you'll just have to check the status of the object once it's created (i.e. set a public property $this->status = 'error'; or something like that to tell you that something bad happened that you'll have to handle).
  3. Create a standalone function to validate the data. Ugly, because this is a function that's specifically related to UserEntity and/or its data.
  4. Or, just create a separate UserData object like you've suggested and be done with it. Much like step # 2, you'll have to have some sort of $status property to indicate a failed validation.

这篇关于将域实体的可变属性存储为值对象是否可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆