Если в 2 словах, то релиз стандарта попал под LTS версию симфони, которая должна была еще н-время поддерживать php5.6. А данный стандарт использовал тип данных object и ограничивал использование версий php 7.0+.
Я не совсем понимаю почему из-за этого нужно было покидать PHP-FIG, так-как на сегодняшний день компоненты симфони поддерживают PSR и PSR-14 тоже доехал.
Разработчики PHP весьма оживились, за последние несколько лет были серьезные прогрессы в производительности, новые фичи, RFC и тп. Технология активно развивается (ждем PHP 8).
Что касается рейтинга: www.tiobe.com/tiobe-index
Мне кажется, это не совсем тот рейтинг, который стоит воспринимать, как показатель жизнеспособности языка(технологии).
Так-как многие инструменты заточены под конкретные ниши и сравнивать их в общем я бы не стал. Например в этот рейтинг на 20 позицию попал Scratch.
PHP достаточно давно и стабильно занял свою нишу и пока все идет хорошо.
Я когда-то давно наступал на посты о том, что разработки PHP крайне аккуратно подходят к фичам, которые ломают обратную совместимость. А такое решение бы похоронило тонны легаси.
Не все так жестоко :). Дальше задаются вопросы по конкретным стандартам, которые используются в нашем проекте. PSR стандарты не так сложно изучить, поэтому их знание скорее небольшой бонус, чем жесткое требование.
Эта тема стабильно поднимается и поднимается. Несколько лет назад я споткнулся где-то рядом habr.com/ru/post/316836.
Возникает тот же вопрос: а зачем это все?
Попробую засветить мысли к которым я пришел. Дело в том, что есть множество RAD-разработчиков, которые практически ничего не использовали за рамками Laravel5 и/или Yii2.
Однако некоторые из них слышали про существование других инструментов, паттернов и тп.
А еще некоторые из некоторых хотят развиваться и далеко не у всех есть верховный маг PHP стоящий выше.
Следовательно такие разработчики читают про что-то новое, в особенности паттерны и бегут это сразу же применять (тут я могу и себе подмигнуть).
Так вот, почти всем нам хорошо известно, что ActiveRecord нарушает принципы SOLID.
Поэтому, если наш AR Repository будет возвращать такую штуку как Model, то можно сделать следующее:
<?php
$post = $repository->find($id);
//...Какая-нибудь проверка с $post->...
$post->published = true;
$post->delete(); // или $post->save() // или $post->{любая магия AR}
$repository->save($post);
В результате чего (особенно если кодовая база большая, подменить реализацию будет практически невозможно, так-как очень сложно отследить подобные места в проекте).
Что касается смены базы данных, поддержки разных баз в AR и тп. Тут нужно кейс рассматривать совсем в другом ключе. Репозиторий это абстракция над хранилищем, а хранилище может быть в другом источнике. Например у вас есть блог на сайте и мы берем данные из нашей базы, а затем у нас появляется кейс, брать данные не из нашей базы, а уже из внешнего ресурса, например стороннего API (какой-то там биржи статей или другого блога). Тогда в теории нам нужно подменить только реализацию, что бы все завелось.
Однако, если у нас нет сущностей и мы гоняем AR Model в репозиториях, то тогда возникнут большие проблемы.
Собственно ключевая особенность RAD-инструмента от Enterprise, как раз в простоте.
Как когда-то мне сказал zelenin, выбирая инструмент нужно принимать правила игры.
Но есть еще 1 момент. Можно использовать Repository не как паттерн абстракции над хранилищем в рамках RAD-инструмента, а как некий класс в котором будут лежать наши запросы для удобства. В таком случае нам и интерфейс не нужен:
<?php
class UserRepository
{
public static function findActiveUsers(): User
{
}
public static function findBestUser(): User
{
}
public static function findBannedUsers(): Users
{
}
...
}
Согласен, однако достаточно избыточно наращивать поверх AR слои с изоляцией, тогда мы теряем все его плюсы. Я в свою очередь очень много спотыкался об подобные вещи, сейчас AR уже давно не использую выбор пал в сторону DataMapper (Doctrine2).
Если уже работать с AR то нужно принять правила игры.
Это я не совсем правильно понял или принцип «LSP» в данном примере суховат?
Особенно неприятно в 2018 году видеть примеры на php без указания типов (возвращаемых значений).
у вас не очень то и репозиторий, больше походит на table gateway.
Ну тут спорный вопрос, так как данные одной сущности могут быть раскинуты на несколько таблиц. К примеру есть сущность Product, у него есть поля name, description и тп. и данные этих полей могут быть в таблице скажем product_translations (да я пока не решился отойти от этого подхода в пользу json).
Тут подробнее. У вас там геттеры/сеттеры или полноценная объектая модель, с логикой в сущностях и тд.
Видимо не натыкался я на примеры с логикой, но в моем понятии сущность — это класс с геттерами и сеттерами, который ничего не делает, кроме как позволяет предоставить контейнер для данных сущности. Как-то я уже натыкался на весьма серьезную проблему (https://habrahabr.ru/post/316836/) и сущности рассматриваю как обертку над данными и единый формат, который можно гонять по проекту, ну скажем если подменить хранилище, то оперируя сущностями приложение не должно заменить, что что-то пошло там поменялось.
Вообще логика — это понятие скольское, так как сегодня это одно, завтра это другое, в том плане, что у меня были частые ситуации, когда нужно было быстро что-то менять. Например попробовали 1 схему, «не зашла», пробуем другую схему (имеется ввиду работа приложения под бизнес). Поэтому теперь я стараюсь очень аккуратно прятать все за интерфейсами, как можно больше разделать и как можно меньше связывать.
UoW нужен не для оптимизации
Походу его основная задача, это (с) "… Реализация паттерна Unit of Work следит за всеми действиями приложения, которые могут изменить БД в рамках одного бизнес-действия. Когда бизнес-действие завершается, Unit of Work выявляет все изменения и вносит их в БД. ..."
у вас слишком уж резкий переход от простого active record к DDD-ной структуре
Много обжигался. Однако не совсем DDD у меня, скорее просто модульная архитектура и стараюсь следовать SOLID. Сейчас мы пилим API, и возможно версия 2 будет разбита на микросервисы и некоторые даже начнут жить по DDD. Однако сейчас просто нет финансовой возможности позволить «жирных» специалистов. Клиент скорее наймет 5 человек за $5000, чем одного. Поэтому как минимум я весь опыт черпаю из неудачных решений проходя через собственные ошибки.
Кто у вас отвечает за сохранение сущности (кто дергает save)?
За сохранение отвечает тот-же репозитроий. Хоть и во круг этого ходят холивары, однако репозиторий это абстракция над хранилищем, поэтому думаю, что методу «сохранить в хранилище» место в репозитории, ну и пока на практике не узнал обратного.
Как разруливаете связи?
AR. Тоесть репозитории и сущности это такая себе абстракция над AR в моем случае.
Что у вас является сущностью?
Взял идею из Symfony. Тоесть у меня есть несколько понятий DTO — класс только с геттерами, который я гоняю между модулями и Сущности, которые в основном находятся в главном модуле Application, и являются практически идентичными как в Symfony.
«я так понимаю что у вас нет UoW»
Да, UoW пока нет, мы только начали пилить проект и подобные штуки я взял на себя смелость внести на этап оптимизации.
Тут проблема в другом. Вам действительно все это надо?
Как показывает практика, если Вы за рамками «бложика» или «сайта-визитки» и требуется постоянно допиливать и обновлять функционал, то подобные вещи весьма кстати.
я сейчас сделал не много по другому.
— сущность
— репозиторий
— для некоторых вещей View Model
А вот реализация уже использует AR. И то очень аккуратно, так как строить запросы в нем очень легко. А с помощью View Model иногда можно возвращать кастомные штуки, чтобы не плодить частичные объекты (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/partial-objects.html).
В теории я тестировал, реализацию можно подменить без проблем, так как на выходе единый формат сущности или view model
Ключевое слово практически. Мое объяснение будет заключатся скорее всего в минусах AR связанных с магией и большой связанность. По мимо этого AR внес весьма солидную путаницу в разработку, а именно теперь большинство разработчиков, а в частности это новички, понимают примерно так:
модель == один класс == active record (я тоже так думал еще 2 года назад).
На примере Eloquent ORM: так есть такие понятия как аксессоры, мутаторы, скопы и тп. Работая со всеми этими терминами в контексте одного класса «модель» становится не много неповоротливой. Дальше более продвинутые новички, которые почитали про «MVC», и узнали примерно такую цитату "… Контроллеры должны быть тонкими, а логика должна быть в модели...", придерживаясь вышеупомянутого сравнения начинают логику писать в моделях (а в 99% это 1 класс).
В результате появляется весьма не очень хорошая практика и очень много не очень хороший статей и видео по теме.
Что касается меня, я не использовал скажем доктрину вне учебных целей, поэтому не могу топнуть ногой и сказать, что я все попробовал на достаточно уровне. Однако сейчас я пишу модульную архитектуру где все-же есть AR, однако он фигурирует только в реализации репозиториев, при этом, что очень важно, из репозиториев возвращаются сущности.
А так все получилось, потому, что очень сложно объяснить новичку, который 10 лет пишет на AR, почему нужно создать еще 5 классов, а не один AR.
Я тоже практически ничего не использовал кроме AR, но он практически всегда приносит жесткий дискомфорт, как только приложения выходит за рамки блога или сайта визитки.
Плюс у AR есть приличное кол-во недостатков, которые уже в моем случае превосходят его преимущества. Поэтому нужно как-то людей толкать в сторону сущностей, репозиториев и дата-маперов.
Подробнее: medium.com/@tdutrion/symfony-and-psr-14-event-dispatcher-f5a9db6740e7
Если в 2 словах, то релиз стандарта попал под LTS версию симфони, которая должна была еще н-время поддерживать php5.6. А данный стандарт использовал тип данных object и ограничивал использование версий php 7.0+.
Я не совсем понимаю почему из-за этого нужно было покидать PHP-FIG, так-как на сегодняшний день компоненты симфони поддерживают PSR и PSR-14 тоже доехал.
Разработчики PHP весьма оживились, за последние несколько лет были серьезные прогрессы в производительности, новые фичи, RFC и тп. Технология активно развивается (ждем PHP 8).
Что касается рейтинга: www.tiobe.com/tiobe-index
Мне кажется, это не совсем тот рейтинг, который стоит воспринимать, как показатель жизнеспособности языка(технологии).
Так-как многие инструменты заточены под конкретные ниши и сравнивать их в общем я бы не стал. Например в этот рейтинг на 20 позицию попал Scratch.
PHP достаточно давно и стабильно занял свою нишу и пока все идет хорошо.
(PHP 5 >= 5.3.0, PHP 7)
Я когда-то давно наступал на посты о том, что разработки PHP крайне аккуратно подходят к фичам, которые ломают обратную совместимость. А такое решение бы похоронило тонны легаси.
По идее да, например Английская система мер и метрическая система мер.
Попробую засветить мысли к которым я пришел. Дело в том, что есть множество RAD-разработчиков, которые практически ничего не использовали за рамками Laravel5 и/или Yii2.
Однако некоторые из них слышали про существование других инструментов, паттернов и тп.
А еще некоторые из некоторых хотят развиваться и далеко не у всех есть верховный маг PHP стоящий выше.
Следовательно такие разработчики читают про что-то новое, в особенности паттерны и бегут это сразу же применять (тут я могу и себе подмигнуть).
Так вот, почти всем нам хорошо известно, что ActiveRecord нарушает принципы SOLID.
Поэтому, если наш AR Repository будет возвращать такую штуку как Model, то можно сделать следующее:
В результате чего (особенно если кодовая база большая, подменить реализацию будет практически невозможно, так-как очень сложно отследить подобные места в проекте).
Что касается смены базы данных, поддержки разных баз в AR и тп. Тут нужно кейс рассматривать совсем в другом ключе. Репозиторий это абстракция над хранилищем, а хранилище может быть в другом источнике. Например у вас есть блог на сайте и мы берем данные из нашей базы, а затем у нас появляется кейс, брать данные не из нашей базы, а уже из внешнего ресурса, например стороннего API (какой-то там биржи статей или другого блога). Тогда в теории нам нужно подменить только реализацию, что бы все завелось.
Однако, если у нас нет сущностей и мы гоняем AR Model в репозиториях, то тогда возникнут большие проблемы.
Собственно ключевая особенность RAD-инструмента от Enterprise, как раз в простоте.
Как когда-то мне сказал zelenin, выбирая инструмент нужно принимать правила игры.
Но есть еще 1 момент. Можно использовать Repository не как паттерн абстракции над хранилищем в рамках RAD-инструмента, а как некий класс в котором будут лежать наши запросы для удобства. В таком случае нам и интерфейс не нужен:
Если уже работать с AR то нужно принять правила игры.
Особенно неприятно в 2018 году видеть примеры на php без указания типов (возвращаемых значений).
Ну тут спорный вопрос, так как данные одной сущности могут быть раскинуты на несколько таблиц. К примеру есть сущность Product, у него есть поля name, description и тп. и данные этих полей могут быть в таблице скажем product_translations (да я пока не решился отойти от этого подхода в пользу json).
Тут подробнее. У вас там геттеры/сеттеры или полноценная объектая модель, с логикой в сущностях и тд.
Видимо не натыкался я на примеры с логикой, но в моем понятии сущность — это класс с геттерами и сеттерами, который ничего не делает, кроме как позволяет предоставить контейнер для данных сущности. Как-то я уже натыкался на весьма серьезную проблему (https://habrahabr.ru/post/316836/) и сущности рассматриваю как обертку над данными и единый формат, который можно гонять по проекту, ну скажем если подменить хранилище, то оперируя сущностями приложение не должно заменить, что что-то пошло там поменялось.
Вообще логика — это понятие скольское, так как сегодня это одно, завтра это другое, в том плане, что у меня были частые ситуации, когда нужно было быстро что-то менять. Например попробовали 1 схему, «не зашла», пробуем другую схему (имеется ввиду работа приложения под бизнес). Поэтому теперь я стараюсь очень аккуратно прятать все за интерфейсами, как можно больше разделать и как можно меньше связывать.
UoW нужен не для оптимизации
Походу его основная задача, это (с) "… Реализация паттерна Unit of Work следит за всеми действиями приложения, которые могут изменить БД в рамках одного бизнес-действия. Когда бизнес-действие завершается, Unit of Work выявляет все изменения и вносит их в БД. ..."
у вас слишком уж резкий переход от простого active record к DDD-ной структуре
Много обжигался. Однако не совсем DDD у меня, скорее просто модульная архитектура и стараюсь следовать SOLID. Сейчас мы пилим API, и возможно версия 2 будет разбита на микросервисы и некоторые даже начнут жить по DDD. Однако сейчас просто нет финансовой возможности позволить «жирных» специалистов. Клиент скорее наймет 5 человек за $5000, чем одного. Поэтому как минимум я весь опыт черпаю из неудачных решений проходя через собственные ошибки.
За сохранение отвечает тот-же репозитроий. Хоть и во круг этого ходят холивары, однако репозиторий это абстракция над хранилищем, поэтому думаю, что методу «сохранить в хранилище» место в репозитории, ну и пока на практике не узнал обратного.
Как разруливаете связи?
AR. Тоесть репозитории и сущности это такая себе абстракция над AR в моем случае.
Что у вас является сущностью?
Взял идею из Symfony. Тоесть у меня есть несколько понятий DTO — класс только с геттерами, который я гоняю между модулями и Сущности, которые в основном находятся в главном модуле Application, и являются практически идентичными как в Symfony.
«я так понимаю что у вас нет UoW»
Да, UoW пока нет, мы только начали пилить проект и подобные штуки я взял на себя смелость внести на этап оптимизации.
Тут проблема в другом. Вам действительно все это надо?
Как показывает практика, если Вы за рамками «бложика» или «сайта-визитки» и требуется постоянно допиливать и обновлять функционал, то подобные вещи весьма кстати.
— DDD
— Entity / VO / DTO
— Repository
и тп.
Ну и Вы про всякие гексагональные архитектуры весьма редко пишите.
— сущность
— репозиторий
— для некоторых вещей View Model
А вот реализация уже использует AR. И то очень аккуратно, так как строить запросы в нем очень легко. А с помощью View Model иногда можно возвращать кастомные штуки, чтобы не плодить частичные объекты (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/partial-objects.html).
В теории я тестировал, реализацию можно подменить без проблем, так как на выходе единый формат сущности или view model
модель == один класс == active record (я тоже так думал еще 2 года назад).
На примере Eloquent ORM: так есть такие понятия как аксессоры, мутаторы, скопы и тп. Работая со всеми этими терминами в контексте одного класса «модель» становится не много неповоротливой. Дальше более продвинутые новички, которые почитали про «MVC», и узнали примерно такую цитату "… Контроллеры должны быть тонкими, а логика должна быть в модели...", придерживаясь вышеупомянутого сравнения начинают логику писать в моделях (а в 99% это 1 класс).
В результате появляется весьма не очень хорошая практика и очень много не очень хороший статей и видео по теме.
Что касается меня, я не использовал скажем доктрину вне учебных целей, поэтому не могу топнуть ногой и сказать, что я все попробовал на достаточно уровне. Однако сейчас я пишу модульную архитектуру где все-же есть AR, однако он фигурирует только в реализации репозиториев, при этом, что очень важно, из репозиториев возвращаются сущности.
А так все получилось, потому, что очень сложно объяснить новичку, который 10 лет пишет на AR, почему нужно создать еще 5 классов, а не один AR.
Плюс у AR есть приличное кол-во недостатков, которые уже в моем случае превосходят его преимущества. Поэтому нужно как-то людей толкать в сторону сущностей, репозиториев и дата-маперов.
Когда у пользователя есть реляция скажем на профиль и на 10 последних почтов, и еще на настройки к примеру.
Это нужно будет самостоятельно все обходить?