OnYourLips: переспрошу - вы про zero-downtime? "другие способы" тоже не атомарны и подразумевают просто минимальный даунтайм. Для zero-downtime деплоймента помимо самого деплоя нужно еще всегда обратную совместимость с базой на одну-две версии приложения держать и еще куча всего. А сделать так что бы даунтайм был порядка милисекунд - ну так я приложил "хак". Если вам уж очень хочется zero-downtime - тоже не проблема - просто придется самому хандлить хосты а не полагаться на встроенный в docker dns сервер.
noway: не правда, вагрант - менеджер виртуалок, а докер - это не виртуалка. То что по керпичикам окружение собрать - это да, но помимо изоляции окружения немаловажно что оно позволяем вам сделать слепок этого окружения в виде образа, и потом дистрибьютить его. Считайте что это RPM на стеройдах.
OnYourLips: код зашит в образ контейнера, так что... был один контейнер с пыхом а стал другой.
vlad tu: нет, ревизия - это деталь реализации статьи по сути. Хотя случаи могут быть разными конечно.
Самый распространенный пример - оформление заказов в интернет магазине, когда у вас есть объект Order, который хранит OrderItem, который хранит ссылку на продукт и количество. А может быть не на продукт а на его копию для архива. А может еще чего. Словом это уже детали реализации. Мы же в основном работаем с Order-ом.
vlad tu: помимо принципа единой ответственности есть еще такая замечательная штука как "высокое зацепление". А у вас зацепление выходит низким.
Поймите, важно не то где поведение находится, а кто знает о внутреннем состоянии объектов. Внешний мир понятия не должен иметь о том, как статья хранит свои ревизии. Их интересуют только конечное состояние. И весь фокус в том, что бы спрятать как можно больше, что бы в случае если мы вместо хранения полноценных копий будем хранить diff-ы текста, нам не пришлось много менять.
vlad tu: у вас логика сущностей по ревизиям вытекла в нейкий RevisionManager. Вот о чем я говорю. То есть поведение, управляющее состоянием объекта Article теперь находится у RevisionManager. Полностью нарушена инкапсуляция. По сути это процедурщина, а не ООП. Но да, так большинство и делают.
vlad tu: вот только в вашем примере это не один вызов. Должно быть тогда уже что-то типа:
$article = Article::create($title, $content);
Тут как бы все довольно просто. А теперь представьте себе что действие что-то делает. Например метод, который публикует статью. Или вносит обновление. И вот вам надо сделать механизм ревизий, и будет уже намного проще, если операция обновление и операция "взять конкретную ревизию" - это будет две отдельные операции.
А вообще - это уже чуть другой уровень судя по вашему коду. Вам же пока рекомендую почитать чего на тему состояния, побочных эффектов, подумать откуда берутся баги и почитать про инкапсуляцию. А ну и еще - почитайте про row data gateway - вы по сути реализовали этот паттерн (а не active record).
Ну вот у вас типичный случай - вам надо что-то создать и потом это что-то отдать обратно пользователю. В этом случае выгоднее использовать отдельно метод, который создает, и отдельно метод, который забирает.
Тут соль в чем, вопервых код сильно упрощается, во вторых завтра вам понадобится не только созданный объект отдать, а еще какую-то доп информацию, и если нет разделения - придется править существующий код, а если бы разделение было - вы бы просто написали новый метод который забирает какие-то данные, а метод который добавляет что-то оставался бы без изменений. Таким образом мы защищаем себя от правок кода. А чем меньше правок - тем меньше шансов сломать код. Ну и тестирование это дико сильно упрощает.
Есть конечно ситуации, когда разделить не выйдет. Например работа со стэком (array_pop) который должен атомарно поменять массив и вернуть удаленное значение. Но вы просто должны делать так, что бы таких штук было по возможности меньше. Принцип "работает не трогай" если хотите, вместо того что бы менять всегда лучше добавить.
Эдуард: еще рекомендую глянуть концепцию middlewares в laravel например. Это те самые адаптеры о которых я говорю. Скажем маршрутизация - так же просто еще один адаптер на пути к вашему контроллеру, который является... по сути последним адаптером в цепочке.
Работа с HTTP - слой адаптеров, контроллеры и т.д. Задача контроллера - конвертировать асинхронное действие пользователя (будь то клик по мышке, http запрос от браузера и т.д.) в синхронный вызов метода модели. Причем по хорошему у нас должен быть ровно один вызов метода модели в контроллере. Тут стоит опять же уточнить - имеется в виду для изменения состояния. То есть если мы вызвали метод что бы поменять состояние и потом хотим вызвать метод что бы забрать какое-то состояние, дабы ответ сформировать - это более чем ок.
Вообще хорошая идея разделять методы на те, что только пишут и те что только читают. Это сильно снижает сложность кода, тестировать такой код одно удовольствие, масштабируется система лучше, а багов становится меньше.
Евгений: может все же дочитайте что это все такое прежде чем задавать такие вопросы?
1) глобальное состояние - это источник большинства багов
2) классы - это... ну типа как объявление класса животных. Они не так важны как объекты но описывают их нутро. Внешнему миру интересно только наружность.
3) все внешние зависимости, вроде коннекшена к базе, должны передаваться явно - то есть через конструктор объекта.
4) не очень хорошая идея подключаться к базе в конструкторе. Удобнее это делать по требованию (ленивая инициализация).
maksjuk11: часть понятий. Представление информации в компьютере и т.д. (типа особенности вычислений с float и т.д.) - это просто информатика и это просто надо знать всем, чья работа связана с вычислительной техникой.
А приведенная книга, это очень хорошо структурированный материал который с большего покрывает все. Задает основы. Вводит основные понятия. Главное отличие оной книги от большинства других - порядок, в котором выдается информация, он логичен. От простого к сложному. От общего к частному. Вообще это считается чуть ли не самой лучшей книгой по этой теме. Даже то что первая редакция вышла в 80-х не меняет ее актуальности сегодня.
Большая же часть книг выпущенных после 2000-ого года учат контроллеры фигачить, на этом далеко не уедешь и понимания вещей не получишь.