Но и сейчас технология программирования не имеет под собой фундаментальной базы типа физики как базы для технических технологий. Ситуация напоминает состояние средневековой техники, когда она не имела под собой научной базы в виде физики. Тогда и появляются проекты вечного двигателя.
Не всякая практическая деятельность может и должна иметь под собой научную основу. Ее создают тогда, когда это необходимо. Сейчас в программировании есть мало что от науки, вы правы, но попытки систематизировать опыт есть, они известны в виде паттернов и принципов проектирования. Так что все впереди. Может так сложиться, что и не потребуется никакая научная основа, если и без нее решаются поставленные задачи.
Наша страна как раз вела себя дружелюбно и миролюбиво, развивала взаимовыгодное сотрудничество, пыталась стать частью мировой экономики. Это другие государства к нашим границам начали подбираться, Россия не могла на это не реагировать.
не пытались ли они вскрыть оборудование, чтобы «скопировать»
Газпром не является производителем оборудования, им это ни к чему, сами они ничего не копируют.
не является ли все это прелюдией для исполнение танца «дайте денег, кругом враги со спутниками».
У них денег и так очень много, одна из богатейших компаний России.
Я думаю, что они просто указали общественности на очередное проявление санционной политики ряда государств в отношении России. Такая политика есть, и она проводится.
А мне статья не понравилась! Она совсем не про совершенный код и рефакторинг. Это очерк из жизни конкретного разработчика, наполненный чувствами, эмоциями и переживаниями. Человек просто ими поделился, вот и всё.
Тогда не надо было вообще про семью упоминать. Чего теперь удивляться, что люди начали комментировать, то, что написано в статье (про брак)? Статья вообще о чем? О ваших чувствах/эмоциях или о рефакторинге?
И все таки мне кажется что если так с Invoice обходиться, то получится, что он будет почти что структурой данных, ведь методы isClosed() и close() это практически геттер и сеттер, не будет ли этого поведения слишком мало (анемия)?:
class Invoice
{
private const CLOSED = 100;
pubic function isClosed() : bool
{
return $this->status == self::CLOSED;
}
public function close() {
$this->status = self::CLOSED;
$this->triggerEvent(new InvoiceClosedEvent($this->id, $this->amount));
}
}
Сейчас у вашего инвойса минимум две отвественности: своё состояние и его синхронизация с внешним сервисом, по какому-то внешнему запросу.
Свое состояние это не ответственность. Ответственность это поведение.
Волне нормальным. Сервис, у которого в зависимостях шлюз и, опционально, репозиторий инвойсов. И в методе checkStatus параметром инвойс или его ид (тогда репозиторий и нужен в заисимостях)
И везде где нужно проверить статус, придется обращаться к этому сервису, передавая ему уже имеющийся инвойс или id
Это как раз и получается God Object (сущность) — одна модель является несколькими кусками приложения.
Нет, не будет это God Object, так как God Object все делает сам, а если есть делегирование другим объектам, то это нормальная инкапсуляция. Если следовать вашей логике, то все фронт-контроллеры это God Object, так как под Application::run() скрывается работа всего приложения.
В моем примере god object нет.
Максимальная инкапсуляция — у God Object. Не знаю таких целей в разработке, как достигнуть расчетной инкапсуляции.
Я знаю, я нигде и не говорил, что должен быть God Ocject. Зачем вы его сюда примешиваете? В моем заминусованном примере Invoice не God Object. Инкапсуляция данных и поведения в объектах должна быть, иначе это не ООП, а процедурное программирование со структурами данных.
Инварианты никогда не страдают, потому что они прописываются в ТЗ.
Но если напрямки не через сервис, обеспечивающий соблюдение инварианта, а через сеттер изменить состояние сущности, где проверка этого инварианта не производится, он может быть нарушен. Пример привести?
вы считаете нормальным внедрять репозитории в сущность, когда бизнес-логика требует каких-то посторонних для сущности данных?
Да, я так считаю. Не понимаю, почему так нельзя, никаких конкретных примеров плохих последствиий такого решения мне никто не привел, все больше «Это плохо потому что так написано там то, это какие-то новые пути для ошибок, побочные эффекты», неубедительно.
entity.command(arguments)
Да я считаю, что в контроллерах можно так делать. Достать сущность, вызвать метод, показать результат выполнения.
А вы попробуйте реализовать, то что вы сказали «счет ничего не будет знать о шлюзе, шлюз о о счете», посмотрим насколько громоздким и объектно-оринтированным будет этот код.
Это уже не просто решение на основе стейта, а полноценный процесс затрагивающий несколько операций, и в котором нужно контроллировать консистентность состояния в двух системах.
Что то вы опять нафантазировали. Какую консистентность контролировать? Просто спросить, оплачен ли счет, и на основе этого изменить стейт.
class Invoice
{
private $payment_gateway;
public function checkStatus()
{
if (!$this->isClosed()) {
$data = $this->payment_gateway->getData($this->id);
if ($this->validate($data)) {
$this->payment_method = $data['payment_methiod'];
$this->close();
}
}
}
}
И полезная вещь здесь — проверка статуса платежа.
А вы AppService, оверинжиниринг это будет. Вместо одного простого метода целый класс прикладного сервиса, с регистрацией в контейнере естественно))).
Сходить во внешний сервис — это не бизнес-логика, это простейшая координация действий. Не происходит изменения стейта, нет риска нарушения инвариантов, это простое чтение данных. Этим может заниматься сервис, для этого нам не нужна наша сущность, и поэтому анемичной она не станет. Если результат из сервиса нужен для логики сущности — вызовите метод сущности передав туда результат который вернул сервис.
А если мне на основании стейта нужно принять решение, ходить ли наружу или нет, а по результатам хождения наружу нужно тоже изменить стейт, здесь тоже предложите в сервис вынести?
Пример требований:
При проверке статуса счета (Invoice), если счет еще не был закрыт, нужно проверить его состояние в платежной системе, проверить соответствие суммы и, если все верно, изменить параметры и состояние счета, а потом закрыть его. Я это делаю в методе Invoice::checkStatus(), в Invoice внедрен шлюз к ПС, который и используется для этой проверки. Это по вашему не бизнес-логика, а «координация действий»? Удивительный темин, кстати.
Внедрять сервисы в сущность в принципе нехорошо. Что с доктриной что без неё.
Мне еще не разу не смогли привести конкретный пример, когда это реально вредило бы.
Внедрять сервисы в сущность в принципе нехорошо. Что с доктриной что без неё.
Ошибаетесь. Вы фантазируете. Я не говорил, что мое единственно верное. Я хочу выслушать аргументы другой стороны. В комментариях здесь же я писал, что штука это рабочая, но я не понимаю, почему она так популярна, если постоянно возникает столько вопросов.
рич модел не о том чтобы весь код приложения находился в сущностях.
Я нигде не утверждал подобное. Снова ваши додумки.
Не всякая практическая деятельность может и должна иметь под собой научную основу. Ее создают тогда, когда это необходимо. Сейчас в программировании есть мало что от науки, вы правы, но попытки систематизировать опыт есть, они известны в виде паттернов и принципов проектирования. Так что все впереди. Может так сложиться, что и не потребуется никакая научная основа, если и без нее решаются поставленные задачи.
Газпром им газ продает и оборудование покупает, взаимовыгодно сотрудничает. Должностные лица в своих заявлениях никогда так не скажут.
Газпром не является производителем оборудования, им это ни к чему, сами они ничего не копируют.
У них денег и так очень много, одна из богатейших компаний России.
Я думаю, что они просто указали общественности на очередное проявление санционной политики ряда государств в отношении России. Такая политика есть, и она проводится.
Свое состояние это не ответственность. Ответственность это поведение.
И везде где нужно проверить статус, придется обращаться к этому сервису, передавая ему уже имеющийся инвойс или id
CheckService::checkInvoice($invoice);
Это процедурная декомпозиция.
Я борюсь со сложностью, с чето вы взяли что нет? Только я пытаюсь бороться объектной декомпозицией, а вы предлагаете процедурную.
Так может просто нет никаких весомых причин не внедрять зависимости в сущности, вы об этом не думали?
Нет, не будет это God Object, так как God Object все делает сам, а если есть делегирование другим объектам, то это нормальная инкапсуляция. Если следовать вашей логике, то все фронт-контроллеры это God Object, так как под Application::run() скрывается работа всего приложения.
В моем примере god object нет.
Я знаю, я нигде и не говорил, что должен быть God Ocject. Зачем вы его сюда примешиваете? В моем заминусованном примере Invoice не God Object. Инкапсуляция данных и поведения в объектах должна быть, иначе это не ООП, а процедурное программирование со структурами данных.
Но если напрямки не через сервис, обеспечивающий соблюдение инварианта, а через сеттер изменить состояние сущности, где проверка этого инварианта не производится, он может быть нарушен. Пример привести?
Да, я так считаю. Не понимаю, почему так нельзя, никаких конкретных примеров плохих последствиий такого решения мне никто не привел, все больше «Это плохо потому что так написано там то, это какие-то новые пути для ошибок, побочные эффекты», неубедительно.
Да я считаю, что в контроллерах можно так делать. Достать сущность, вызвать метод, показать результат выполнения.
Что то вы опять нафантазировали. Какую консистентность контролировать? Просто спросить, оплачен ли счет, и на основе этого изменить стейт.
И полезная вещь здесь — проверка статуса платежа.
А вы AppService, оверинжиниринг это будет. Вместо одного простого метода целый класс прикладного сервиса, с регистрацией в контейнере естественно))).
А если мне на основании стейта нужно принять решение, ходить ли наружу или нет, а по результатам хождения наружу нужно тоже изменить стейт, здесь тоже предложите в сервис вынести?
Пример требований:
При проверке статуса счета (Invoice), если счет еще не был закрыт, нужно проверить его состояние в платежной системе, проверить соответствие суммы и, если все верно, изменить параметры и состояние счета, а потом закрыть его. Я это делаю в методе Invoice::checkStatus(), в Invoice внедрен шлюз к ПС, который и используется для этой проверки. Это по вашему не бизнес-логика, а «координация действий»? Удивительный темин, кстати.
Мне еще не разу не смогли привести конкретный пример, когда это реально вредило бы.
Ошибаетесь. Вы фантазируете. Я не говорил, что мое единственно верное. Я хочу выслушать аргументы другой стороны. В комментариях здесь же я писал, что штука это рабочая, но я не понимаю, почему она так популярна, если постоянно возникает столько вопросов.
Я нигде не утверждал подобное. Снова ваши додумки.