Расширение класса внешними методами и переменными

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@whirlwind в большинстве случаев я вычищаю код от трейтов и прочих mixin вроде поведений, потому что обычно проще выкинуть сторю из проекта, обсудив с owner-ом оценку объема работы, чем отдебажить

тут специальная тема о способах добраться до зубов через анус
 

Yoskaldyr

"Спамер"
Партнер клуба
Кстати появилось предложение от nikic насчет декораторов

Все вышеописанные извращения можно будет делать через такие декораторы, с точки зрения кода практически ничего не поменяется (разве что будет вызов не парента, а декорируемого класса). Главный плюс не надо писать кучу магии и все хорошо будет работать в долго играющих приложениях (swoole, php-pm, reactphp и т.п.)
 

AmdY

Пью пиво
Команда форума
Похоже это хотелка от Стаса, у нас на проекте декоратор был главным костылём для расширения функционала. Но вылезала проблема с большим количеством копи-паста и приватными методами. Лучше всё же чтобы архитектура изначально готовилась к расширению, а не костылись их декоратором.
 

Yoskaldyr

"Спамер"
Партнер клуба
@AmdY Когда пишешь свое, то что декоратор, что все извращения из данной темы не нужны
А вот когда коробочное "чудо" типа XenForo и Magento, то такие декораторы будут очень кстати и более правильно чем костыль с наследованием.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
В php team очень серьезные вещи обсуждают сейчас касательно будущего php

по синтаксису смое любопытное, кстати - Write-Once Properties
 

Yoskaldyr

"Спамер"
Партнер клуба
по синтаксису смое любопытное, кстати - Write-Once Properties
на реддите было довольно активное обсуждение. И лично я согласен с некоторыми - такой вариант не очень, лучше как readonly в других языках. Т.е. получать невалидный объект после конструктора совсем не айс. И аргументы, что это нужно для лезилоада, тоже не в тему, т.к. плюсов минимум, а минусов значительно больше.
 

fixxxer

К.О.
Партнер клуба
В php опять свой путь ищут, вместо того, чтобы просто взять и сделать как в Java.

Аргументы про lazy load могут приводить только совсем ушибленные, какой в задницу lazy load для immutable object?
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer так это аргумент от автора предложения :(((
Еще не хватает раздельного доступа - только чтение извне объекта, а изменение только из самого объекта. Понятно что все это можно делать магией, но лучше когда это синтаксисом и описанием объекта делается
 

fixxxer

К.О.
Партнер клуба
Да автор тоже ушибленный. :) "writeonce", блин, это смешно обсуждать даже
Еще не хватает раздельного доступа - только чтение извне объекта, а изменение только из самого объекта.
Это тот случай, когда геттер - нормально. Тем более, что всегда, когда появляется такой геттер, надо задать себе вопрос "а не фигню ли я делаю" и пройтись по пяти буковкам в SOLID. С большой вероятностью геттер не выживет в ходе этой процедуры.
 

Yoskaldyr

"Спамер"
Партнер клуба
тупо бы перенесли из c# public int MyInt{ get; private set; } + readonly.... Так нет придумывают извращения
 

Yoskaldyr

"Спамер"
Партнер клуба
писать руками геттеры когда свойств дофига и больше - явное извращение. И это вообще ник ак не нарушает SOLID, и даже сейчас все можно делать через магию, но лучше явное использование, чем неявное
 

AnrDaemon

Продвинутый новичок
А сделать синтаксис типа

Код:
property type $var [write methodName];
не? Если нет метода записи, будет "public read-only".
 

fixxxer

К.О.
Партнер клуба
писать руками геттеры когда свойств дофига и больше - явное извращение. И это вообще ник ак не нарушает SOLID, и даже сейчас все можно делать через магию, но лучше явное использование, чем неявное
В случае с public final никаких геттеров и не потребуется.

А если тебе понадобились геттеры и это не immutable value object[/read model/dto], а что-то еще, то надо сначала задаться вопросом, что за фигню ты написал. Какой-нибудь active record небось. Случаев, когда это осмысленнный дизайн, достаточно немного, чтобы было не страшно сгенерить геттер (да, phpstorm уже умеет).
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer Никакой не эктив рекорд.
Есть объект со свойствами (много полей), свойства можно задать только через конструктор и мутировать внутренний стейт можно только заданными методами (не сеттерами, а именно комплексными изменениями). Сейчас это решается только через приват параметры + меджик геттер. Но это совсем не явно, а магия. Нет нормального автокомплита (без танцев с бубном и аннотациями). Лучше когда оно было бы явно.
А прописывать на все 100500 полей явные геттеры - это вообще треш.
Единственные явные геттеры что есть в этих объектах - это какие либо computed поля. и все.
И здесь нет вообще никакого нарушения SOLID или еще чего умного что здесь на форуме любят сначала додумать, а потом приплести в обсуждение. Классическое ООП - просто данные вместе с их поведением (в конкретном случае изменение внутреннего стейта).

Полностью иммутабельные объекты - это немного другое.
 

fixxxer

К.О.
Партнер клуба
Есть объект со свойствами (много полей), свойства можно задать только через конструктор и мутировать внутренний стейт можно только заданными методами
Это ок, так устроен любой мутабельный объект с состоянием.


Сейчас это решается только через приват параметры + меджик геттер.
А зачем тут геттер понадобился, неясно.
 

Yoskaldyr

"Спамер"
Партнер клуба
А зачем тут геттер понадобился, неясно.
А как еще получать приватные поля объекта? Или явный геттер (что полный бред на 100500 полей даже с автогенерацией - это мусор а не код) или __get. Или есть еще простые и явные способы получить доступ к извне к приватным свойствам? Конечно можно делать свойства паблик, но тогда кто угодно может их менять извне.
 

Yoskaldyr

"Спамер"
Партнер клуба
думаю неплохо было бы вынести отдельно обсуждение этого нового rfc
 

fixxxer

К.О.
Партнер клуба
А зачем получать приватные поля объекта? Они на то и приватные, чтобы их не получать извне. Инкапсуляция называется. При вменяемой архитектуре снаружи объект - это черный ящик, и о его внутреннем состоянии ничего не известно.

Для особых случаев (ORM, serializer...) есть reflection.

Value objects - это особый частный случай, это и не объект даже, а кастомный тип данных, типа структуры в С.
 

Yoskaldyr

"Спамер"
Партнер клуба
А зачем получать приватные поля объекта
А их надо получать только потому, что они публичные, но сделаны приватными только для того чтобы их нельзя было изменить извне!
А так это полностью публичные данные - контракт объекта. И задача объекта предоставлять эти данные (его основная задача). Как вторая задача мутировать эти собственные публичные данные, а также дополнительный скрытый стейт (скрытый стейт не доступен извне, на то он и скрытый). И когда этих необходимых публичных данных немного - пофиг можно сделать явный геттер, но когда этих полей больше 20 объект получается на 90% состоящий из бестолковых геттеров (классический пример кода ради кода). А рефакторить потом это когда какие-либо поля меняются вообще одно удовольствие...
Value objects - это особый частный случай, это и не объект даже, а кастомный тип данных, типа структуры в С.
Да, частный, но это не отменяет что их тоже надо как-то делать.

А то уже несколько лет как мода пошла - пишем явное гавно, знаем что гавно, знаем что из-за тяжелого наследия пхп и/или недостающего синтаксиса. Но начинаем аргументировать высокими материями, что типа так и надо и это правильно.

В горячо любимом многими здесь на форуме сишарпе это давно есть и активно применяется.
 

fixxxer

К.О.
Партнер клуба
Да, частный, но это не отменяет что их тоже надо как-то делать.
Как их делать, понятно - сделать public final.

публичные данные - контракт объекта
Такой контракт допустим только для value objects (которые в идеале должны быть immutable). То, что ты описываешь, это какая-то очень хреновая архитектура.

Понятно, что геттерно-выглядящие методы могут быть, но контракт не может быть равен внутреннему состоянию, это нонсенс, это вообще не ООП, а структуры и процедуры. Возьмем, например, DateTime (даже не immutable). Как внутри там представлены дата и время - а фиг его знает, это пользователя класса не волнует.
 
Сверху