丰富的域模型和表单映射

时间:2016-09-29 20:46:38

标签: javascript php forms domain-model rich-domain-model

TLDR:如何将富域模型与“重”设置器与简单的HTML表单映射相结合?

当一个属性的setter更改其他属性时(直接或使用setter - 这没关系)会出现问题。

用于更好解释的示例类(在PHP中,但这没关系 - 我认为):

class Product {

private $name;
private $cost;
private $profit;
private $price;

public function getName() {
    return $this->name;
}

public function getCost() {
    return $this->cost;
}

public function getProfit() {
    return $this->profit;
}

public function getPrice() {
    return $this->price;
}

public function setName($name) {
    $this->name = $name;
    return $this;
}

public function setCost($cost) {
    if ($this->cost !== $cost) {
        $this->cost = $cost;
        $this->setPrice($this->getCost() + $this->getProfit());
    }
    return $this;
}

public function setProfit($profit) {
    if ($this->profit !== $profit) {
        $this->profit = $profit;
        $this->setPrice($this->getCost() + $this->getProfit());
    }
    return $this;
}

public function setPrice($price) {
    if ($this->price !== $price) {
        $this->price = $price;
        $this->setProfit($this->getPrice() - $this->getCost());
    }
    return $this;
}

}

这个想法是这样的:你可以设定成本(购买/创造产品)和你想赚取的利润 - 然后计算价格(销售产品)。此外,您可以设置更改价格 - 然后计算利润。 (改变成本可能会触发改变利润而不是价格,但问题并不重要。)

例如:

$foo = new Product();
$foo->setName("Foo");
$foo->setCost(100);
$foo->setPrice(110);
assert($foo->getProfit() == 10);
$foo->setProfit(30);
assert($foo->getPrice() == 130);

由于许多原因(即命令行前端和CRON作业),我需要在“后端”代码中拥有丰富的对象。

在HTML前端,您可以获得与成本,利润和价格相对应的3个输入的表单。当用户更改值并提交setter的表单顺序很重要并且可能会搞砸。例如:

  • 用户单击以编辑产品按钮
  • 看到表格的值:成本= 100,利润= 10,价格= 110
  • 将利润变为20
  • 提交表格

问题是:后端映射器从POST表单获取值并调用:setCost(100),setProfit(20)然后setPrice(110)这是坏的,因为它是旧的价格,应该更改为120(用户希望获得20个利润和100个成本)。

我看到的唯一解决方案是在前端实现所有域模型逻辑 - 在JavaScript中 - 因此更改成本/利润输入会触发更改价格输入中的值。然后所有输入都有正确的值,并且可以放置POSTed数据而不会出现“覆盖”问题。这个样本很容易,但是如果你有很多字段(耗时且容易在两种不同的语言中编写相同的代码)或者它们之间真的很复杂的逻辑(不是一切都可以在JS中轻松实现),那就不可能了。

任何想法如何解决这个问题? :)

PS:使用瞬态属性和延迟评估(即只有成本和价格是属性和可编辑的,并且总是计算利润)不是一种选择。我必须能够从两个方面改变。此外,对于一些繁重的计算也不方便 - 所有道具必须存在然后保存到数据库中。

1 个答案:

答案 0 :(得分:0)

如果你处理遗留代码,一个选项是发送一个请求到后端进行字段更改并检索更新的字段作为响应,所以基本上在前端你必须imlement只表单更新。但这不是一个很好的解决方案,我宁愿专注于真正需要为用户提供的应用程序。如果你让用户chane所有3个字段,你为什么要偏执。他知道他做得对吗?或者,如果您有验证规则,则在提交时进行评估。您可能已经看到需求如何改变您的行为。