anton_z писал(а): ↑2019.05.04, 03:11
Тогда можно сделать вывод что ООП может существовать без DDD, нормальный код может существовать без DDD, тесты могут существовать без DDD. DDD вещь дополняющая. Вопрос: зачем нужен DDD если и без него можно получить хороший объектно-ориентированный код?
Да, верно.
TDD и BDD - методология поверх тестов, советующая, как сделать тесты полезнее. Но тесты можно делать любыми способами без TDD и BDD. DDD - это методология поверх ООП, советующая, как спроектировать модель удобнее. ООП тоже можно делать как угодно без всяких DDD.
TDD лишь дополнительно советует делать тесты одновременно с кодом. BDD говорит записывать тесты языком человекочитаемых юзкейсов. DDD говорит делить сложные системы на контексты, выработать общий язык и придерживаться этого языка при проектировании объектов.
ElisDN писал(а): ↑2019.05.03, 16:38
В книгах Вернона отвязка от базы и абстракция домена от инфраструктуры (фреймворка) описана как часть DDD. В примерах на github все это тоже есть. Книга Вернона считается основополагающей для DDD наравне с Эвансом. Или Вернон ошибается и он сам Эванса не понял?
Ключевое - абстракция домена от нечистых технических вещей. Инкапсуляция всего технического в инфраструктуру. Чтобы думать смыслами, а не деталями.
Вот недо-ООП-код без DDD:
Код: Выделить всё
public function handle(Command $command): void
{
$email = mb_strtolower($command->email);
if ($this->em->getRepository(User::class)->findOneBy(['email' => $email])) {
throw new \LogicException('User already exists.');
}
$user = new User();
$user->setId(Uuid::uuid4()->toString());
$user->setDate(new \DateTimeImmutable());
$user->setEmail($email);
$user->setPasswordHash(password_hash($command->password, PASSWORD_ARGON2I));
$user->setConfirmToken(bin2hex(random_bytes(16));
$user->setStatus(User::STATUS_WAIT);
$this->em->persist($user);
$this->em->flush();
$message = (new \Swift_Message('Sig Up Confirmation'))
->setTo($email)
->setBody($this->twig->render('mail/user/signup.html.twig', ['token' => $token]), 'text/html');
$this->mailer->send($message);
}
Вот ООП-код с DDD:
Код: Выделить всё
public function handle(Command $command): void
{
$email = new Email($command->email);
if ($this->users->hasByEmail($email)) {
throw new UserAlreadyExistsException();
}
$user = User::signUpByEmail(
Id::next(),
new \DateTimeImmutable(),
$command->username,
$email,
$this->hasher->hash($command->password),
$token = $this->tokenizer->generate()
);
$this->users->add($user);
$this->sender->send($email, $token);
}
Коды делают то же самое.
Но в первом программист бездумно клепал как есть и получилось, что всё идёт простынёй вперемешку с непонятными техническими bin2hex и PASSWORD_ARGON2I и Swift_Mailer.
А во втором программист по-настоящему заморочился с ООП и все эти инфраструктурные вещи вроде bin2hex(random_bytes(16)) инкапсулировал в понятные абстракции по смыслу вроде $tokenizer->generate(). И получил компактный понятный человекочитаемый код, очищенный от неинтересного технического мусора. Даже уборщица в любой строке разберётся.
И, как бонус, код второго метода handle теперь автоматически получился фреймворконезависимым, так как теперь внутри TokenSender::send можно спокойно заменить SwiftMailer на Mailgun API. Да и даже с PHP в Java можно один-в-один перенести, поправив синтаксис.
Так что фреймворконезависимость здесь оказалась не целью, а результатом. Если при продумывании ООП-модели так думать о домене, то естественным образом получается DDD-совместимый ООП-код.
anton_z писал(а): ↑2019.05.04, 03:11
P.S. Вспомнил что еще не нравится в DDD, так это методика Code First. По моему она ставит вещи с ног на голову. Посмотрим внимательнее на термин "data base". Что значит слово "base"? Оно означает "фундамент", "основа".
Это как у Задорнова "стоматолог = матершинник", а "голосистая = девушка без бюстгальтера".
anton_z писал(а): ↑2019.05.04, 03:11
Именно данные это основа большинства информационных систем, к коим и относятся большая часть всех приложений для бизнеса. Помню, на каком-то из Хайлоадов (речь о конференции) один докладчик говорил про то, что они нащупали универсальную методику разработки высоконагруженных систем. И первый вопрос на который они предлагают найти ответ: что у вас за данные? Так вот поэтому я считаю, что именно с данных и надо все начинать.
Ещё он говорил, что ваш код - это прослойка между браузером и БД.
Если это
информационная система, записывающая и предоставляющая информацию, то её основа - это хранение статических данных. Надо начинать с раскладывания данных и можно забить на то, какая неудобная админка для их вбивания.
Если это
система автоматизация бизнеса, то её основа - алгоритмы динамических бизнес-процессов. Надо начинать с бизнес-процессов и можно забить на то, как и где они хранятся. Хоть в file_put_contents(..., serialize($object)).
Так что не смешивайте всё в одну кучу.
anton_z писал(а): ↑2019.05.04, 03:11
Тем более что СУБД в последние годы не стоят на месте, а SQL это отличный декларативный язык, позволяющий удобно обрабатывать данные. После того, как база спроектирована, ООП нам поможет сделать хорошее приложение, помимо всего прочего генерирующее правильные запросы к СУБД. Конечно, по ходу разработки приложения в схему данных могут быть внесены корректировки, куда ж без них.
Это просто сказывается ваша зацикленность только на табличных SQL базах. Вы все таблицы, значения, документы, графы и объекты загоняете костылями в MySQL. Вместо того, чтобы для таблиц, значений, документов, графов и объектов использовать специально для них придуманные табличные, key-value, документные, графовые и объектные БД.
anton_z писал(а): ↑2019.05.04, 03:11
А Code First нам предлагает базу воспринимать как что-то второстепенное, хотя это вещь важнейшая.
Повторюсь. что не всегда эта вещь важнейшая.
Если кода мало, то CRUD с DB-First. Если кода много, то Domain Model с Code First.