Применяется ли разделение команда / запрос к методу, который создает объект и возвращает его идентификатор?

12

Давайте представим, что у нас есть сервис, который вызывает бизнес-процесс. Этот процесс вызовет слой данных для создания объекта типа A в базе данных.

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

В первом методе мы создаем объект (изменить состояние) и возвращаем его идентификатор (запрос) в одном методе.

Во втором методе у нас есть два метода: один (createA) для сохранения и другой (getId) для запроса.

    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);           
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }

Из моего понимания второй метод более полно следует за разделением командных запросов. Но я считаю расточительным и нелогичным запрашивать базу данных, чтобы получить объект, который мы только что создали.

Как вы согласовываете CQS с таким сценарием?

Только ли второй метод следует за CQS, и если да, то предпочтительнее ли использовать его в этом случае?

жилль
источник
2
если A и B создаются вместе с какой-либо частотой, я бы, вероятно, заставил бы хранимую процедуру создать оба сразу, а затем вы исключили бы возможность создания B первым или создания A без B, если это проблемы.
Ryathal
Войдя в конце игры, вы можете использовать параметр out. Технически это не возвращаемое значение! ;)

Ответы:

13

CQS - это скорее руководство, а не абсолютное правило. В вики-статье приведены примеры действий, которые невозможны при строгом CQS.

Однако в этом случае, если вы хотите сохранить CQS, вы можете либо создать идентификатор на стороне клиента (например, GUID), либо клиент может запросить идентификатор из системы, прежде чем создавать какие-либо объекты, которые кажутся более чистыми для мне, чем создать объект, а затем запросить его (но сложнее, чем просто использование столбца идентификации).

Лично я бы просто вернул ID и назвал его одной из тех ситуаций, когда CQS не подходит.

Еще одна хорошая статья с примерами: Мартин Фаулер

Мисько
источник
3

Если вы следуете методологии, и она, кажется, ведет вас по неверным путям, вам следует переоценить ее.

Я вижу, что идентификатор вновь созданного объекта является допустимой вещью, которую нужно иметь в качестве возвращаемого параметра - это не только удобно, но и «хорошо» - как вы можете видеть, код лучше, когда он это делает.

В любом случае, я не знаком с «разделением командных запросов», но я очень сомневаюсь, что он запрещает командам возвращать информацию о выполнении команд, и если это так, просто выкидывает это - успех / неудача всегда есть, и я делаю не думайте, что «ваш объект был создан нормально» из «ваш объект был создан хорошо, а его идентификатор - ххх», чтобы сильно отличаться.

Алекс
источник
-1

Только второй метод следует за CQS.

Я считаю, что CQS - это руководство, поощряющее хорошие практики кодирования. Используйте хорошие методы кодирования во время разработки, и если позже вы обнаружите, что этот метод содержит критичный для ресурсов код, вы все равно можете оптимизировать его.

Преждевременная оптимизация - корень всего зла :)

cheesus говорит прекратить стрельбу модов
источник
Что особенно хорошо во втором методе?
CheatEx
Я не сказал, что второй метод - «хорошо». Я сказал, что это следует парадигме CQS. Если вы не следуете CQS, я полагаю, что второй метод не подходит для вас. Если вы хотите знать , почему некоторые люди пытаются следовать CQS см http://en.wikipedia.org/wiki/Command-query_separation
cheesus говорит прекратить огонь модники
Вы сказали, что CQS поощряет хорошие методы кодирования, если это правда, тогда мы должны наблюдать некоторую «доброту» во втором методе. Где это?
CheatEx
Видимо, вы не читали ссылку, которую я предоставил. Фраза CQS: задавая вопрос, вы не должны менять ответ . В вашем первом методе у вас есть метод («createA»), который предоставляет «ответ», но он меняет ответ каждый раз, когда вы спрашиваете. Во втором методе у вас этого нет, это «добро». Чтобы было ясно: я не пурист CQS, я не следую этому каждый раз.
говорит cheesus, прекратить стрельбу из модов 14.12.11