Богатая модель домена и отображение форм

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 входами, соответствующими стоимости, прибыли и цене. Когда пользователь меняет значения и отправляет форму, порядок установки имеет значение и может испортить ситуацию. Например:

  • пользователь нажимает кнопку для редактирования продукта
  • видит форму со значениями: стоимость =100, прибыль =10, цена =110
  • меняет прибыль до 20
  • представить форму

И проблема в том, что: Backend mapper получает значения из формы POST и вызывает: setCost(100), setProfit(20) и затем setPrice(110), что плохо, потому что это старая цена, которая должна быть изменена на 120 (пользователь хотел получить 20 прибыль и 100 стоимость).

Единственное решение, которое я вижу, состоит в том, чтобы реализовать всю логику модели предметной области также во внешнем интерфейсе - в JavaScript - поэтому изменение входных данных "затраты / прибыль" вызывает изменение значения при вводе цены. Тогда все входные данные имеют правильные значения и POST-данные могут быть помещены без "переопределения" проблемы. Это легко сделать с помощью этого примера, но невозможно, когда у вас много полей (много времени и ошибок при написании одного и того же кода на двух разных языках) или действительно сложная логика между ними (не все легко реализовать в JS).

Есть идеи как решить это?:)

PS: использование переходных свойств и ленивая оценка (т. Е. Только стоимость и цена являются собственностью и доступны для редактирования, а прибыль всегда рассчитывается) не вариант. Я должен быть в состоянии измениться с обеих сторон. Также это неудобно для некоторых тяжелых вычислений - все реквизиты должны присутствовать и затем сохраняться в базе данных.

1 ответ

Если вы имеете дело с унаследованным кодом, одним из вариантов будет отправка запроса бэкенду об изменении поля и получение обновленных полей в ответ, так что, в основном, в интерфейсе вы должны реализовывать только обновление формы. Но это не очень хорошее решение, я бы лучше сконцентрировался на том, что приложение действительно должно предоставить как ценность для пользователя. Если вы позволите пользователю изменить все 3 поля, почему вы должны быть параноиком? он знает, что он делает правильно? Или, если у вас есть правила проверки, оцените при отправке. Вы, наверное, уже видите, как требования могут изменить ваше поведение.

Другие вопросы по тегам