Pull to refresh

Comments 6

Зачем нужно создавать отдельный трейт WithCustomerInfo? Выглядит как будто его функции будут использоваться только в CustomerView, а если где-то еще нужна будет эта информация, то будет использоваться сам CustomerView

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

Получение acf полей и стандартных данных типа get_the_title и так ведь кэшируется на текущий запрос. Или имеется ввиду случаи, когда перед выводом с данными происходят дополнительные трансформации?

Зачем нужно создавать отдельный трейт WithCustomerInfo? Выглядит как будто его функции будут использоваться только в CustomerView

Действительно, если методы будут использоваться только в CustomerView, то следует писать их прямо там без трейта. Я дергал для примера куски кода из разных проектов, в данном случае было два вида клиентов: компании и физлица, часть их полей пересекалась в трейте WithCustomerInfo

Получение acf полей и стандартных данных типа get_the_title и так ведь кэшируется на текущий запрос. Или имеется ввиду случаи, когда перед выводом с данными происходят дополнительные трансформации?

Все так. Кеширование необходимо в случаях, если в методе присутствуют какие-либо дополнительные вычисления. Особенно, если они касаются запросов к базе.

С другой стороны, если внутри метода вызывается что-либо, что может быть переопределено через хук, то мы не можем быть уверены, что оно всегда будет работать быстро. Особенно если проект большой и разработчиков на нем более чем один, или если среди разработчиков есть нейросети. Поэтому кешированием стоит пренебрегать только если вы на 100% уверены, что повторный вызов метода не будет генерировать дополнительных запросов к БД или выполнять что-нибудь ресурсозатратное.

Решение защитить классы-конфиги типа Customer.php синглтоном от повторного вызова как будь-то бы спорное. Если все эти классы всё равно централизованно находятся автопоиском и инициализируются в

private function load($namespace): void

не проще ли гарантировать однократную загрузку именно на этом уровне?

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

Решение защитить классы-конфиги типа Customer.php синглтоном от повторного вызова как будь-то бы спорное. Если все эти классы всё равно централизованно находятся автопоиском и инициализируются в private function load($namespace): void не проще ли гарантировать однократную загрузку именно на этом уровне?

Не проще, потому что это не гарантирует однократную загрузку. Сейчас вы физически не можете написать new Customer();, интерпретатор выдаст ошибку. Вы можете обратиться к классу Customer только через метод instance(), возвращающий уже созданный на этапе первого обращения к классу объект.

Невозможно создать объект Customer через new, т.к. его конструктор приватный
Невозможно создать объект Customer через new, т.к. его конструктор приватный

А обращаться к классу Customer извне у вас может быть масса причин. Например, поступила задача выдать каждому клиенту рейтинг и обновлять его запросами к внешней CRM. За связь с CRM у вас отвечает отдельный плагин. Внутри этого отдельного плагина вы можете по API получить новый рейтинг для клиента и обновить его примерно так Customer::instance()->updateRating($customerId, $ratingValue); , если бы у вас не было реализации одиночки, вам бы пришлось либо создать статический метод Customer::updateRating(int $customerId, int $ratingValue) и обновлять сервис через него, в этом случае вы не смогли бы обращаться к нестатическим свойствам и методам класса внутри статического. Либо где-то хранить созданный на этапе загрузки приложения объект класса Customer, чтобы к нему обращаться повторно. Так вы бы изобрели что-то вроде обрезанного сервис-контейнера из Laravel, от куда можно извлечь нужный объект. А в конечном счете пришли бы к singleton-объектам внутри этого контейнера, чтобы избежать их дублирования. Потом бы устранили этот DI на минималках, поскольку выяснилось бы, что для вас оптимальным вариантом будет, если все объекты сущностей будут одиночками и вам не нужно дополнительное усложнение в виде их хранилища, достаточно сделать их доступными глобально. Я, по крайней мере, прошел этим путем :)

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

При необходимости отключить любую сущность можно закомментировав вызов $this->init(); внутри метода initInstance() соответствующей сущности.

Про неявность загрузки согласен, но лично мне так удобнее, потому что тех же классов твиков и блоков могут быть десятки и даже сотни. Следить за подключением каждого мне откровенно лень.

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

Из явных недостатов автозагрузки я столкнулся только с тем, что мне потребовалось несколько раз поменять очередность инициализации разных сущностей. Для этого я добавил в класс IzwpCustomEntities\Core\BaseEntities\CustomFields , от которого наследуются прочие классы сущностей, свойство $loadPriority, где можно задать приоритет инициализации и перекинуть включение части функционала в конец.

А, Customer не просто конфиг, он БЛ может быть еще обвешан, понял. Я обычно отделяю слой регистрации (конфигураторы посттайпов, полей, такс итп), от прочей логики. Тонкие классы, назовем к примеру CustomerInit - отвечают только за регу, переводы подбрасывают, чпу настраивают. То есть дальше в жизни приложения не участвуют, и нет смысла дергать их где-то еще. Бутстрап отдельно от логики.

Показалось что здесь подобный подход. Классы монолиты которые отвечают за все про все - наводят осеннюю грусть)

А, Customer не просто конфиг, он БЛ может быть еще обвешан, понял. Я обычно отделяю слой регистрации (конфигураторы посттайпов, полей, такс итп), от прочей логики. Тонкие классы, назовем к примеру CustomerInit - отвечают только за регу, переводы подбрасывают, чпу настраивают. То есть дальше в жизни приложения не участвуют, и нет смысла дергать их где-то еще. Бутстрап отдельно от логики.

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

Показалось что здесь подобный подход. Классы монолиты которые отвечают за все про все - наводят осеннюю грусть)

Эти классы редко состоят более чем из 5-7 методов. Создавать на каждый метод отдельный класс - занятие довольно бессмысленное, вы просто получите больше файлов без каких-либо преимуществ. Если класс разрастается, то эту логику следует выносить в отдельный сервис, плагин, библиотеку. Об этом написано в статье:

Sign up to leave a comment.

Articles