0

TLDR: リッチ ドメイン モデルと「重い」セッターを単純な HTML フォーム マッピングと組み合わせる方法は?

あるプロパティのセッターが他のプロパティを変更すると問題が発生します (直接またはセッターを使用して - これは問題ではありません)。

よりよく説明するためのサンプルクラス(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 つの入力を含むフォームを取得します。ユーザーが値を変更してフォームを送信すると、セッターの順序が問題になり、混乱する可能性があります。例えば:

  • ユーザーは製品ボタンをクリックして編集します
  • 次の値を持つフォームを見る: cost=100、profit=10、price=110
  • 利益を 20 に変更します
  • フォームを送信

問題は、バックエンド マッパーが POST フォームから値を取得し、setCost(100)、setProfit(20)、次に setPrice(110) を呼び出すことです。これは、120 に変更する必要がある古い価格であるため、不適切です (ユーザーは 20 を希望していました)。利益と 100 コスト)。

私が見る唯一の解決策は、すべてのドメイン モデル ロジックをフロントエンド (JavaScript) にも実装することです。そのため、コスト/利益入力を変更すると、価格入力の値が変更されます。次に、すべての入力に正しい値があり、POST されたデータは「オーバーライド」の問題なしに配置できます。このサンプルでは簡単ですが、多くのフィールドがある場合 (2 つの異なる言語で同じコードを記述すると時間がかかり、エラーが発生しやすくなります)、またはそれらの間のロジックが非常に複雑な場合 (すべてが JS で簡単に実装できるわけではありません) の場合は不可能です。

これを解決する方法はありますか?:)

PS: 一時的なプロパティと遅延評価 (つまり、コストと価格のみがプロパティであり、編集可能であり、利益は常に計算されます) を使用することはできません。私は両方の方法から変更することができなければなりません。また、一部の重い計算には不便です。すべての小道具が存在し、データベースに保存する必要があります。

4

1 に答える 1

0

レガシー コードを扱う場合、フィールドの変更時にバックエンドにリクエストを送信し、それに応じて更新されたフィールドを取得するというオプションがあるため、基本的にフロントエンドではフォームの更新のみを実装する必要があります。しかし、これは良い解決策ではありません。アプリがユーザーに価値を提供するために本当に必要なものに集中したいと思います。ユーザーに 3 つのフィールドすべてを変更させた場合、なぜ偏執的になる必要があるのでしょうか。彼は自分が何をしているのか知っていますか?または、検証ルールがある場合は、送信時に評価します。要件によって行動がどのように変化するかは、おそらくすでにおわかりでしょう。

于 2016-09-30T17:28:55.550 に答える