-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3.4. Модификаторы доступа для свойств #26
Comments
eval, goto, global - тоже стандартная часть языка...)) Можете привести пример? UPD Если вы про статику - это способ защиты от выстрела себе в ногу. Если без статики вот ну вообще никак - можно воспользоваться "Здравым Смыслом". Но это очень плохой маячок, вероятно архитектура спроектирована не качественно. Если вы про public - это в принципе вопрос безопасности, я в курсе по 7.4, такой позволяет защититься как от в принципе не валидных данных, так и дает контроль над доступом к этим данным. |
Пример DTO и синглтона. До добавления возможности хранить массивы в константах класса, единственной альтернативой были статичные свойства. Да и сейчас по моему не все можно хранить в константах. Синглтон хоть и антипаттерн, но есть кейсы где он необходим. Как и для goto есть кейсы. |
С DTO нет никаких проблем, да с геттерами и сеттерами. |
И получаем потерю в производительности и ухудшение читаемости на ровном месте только из того, что проигнорировали стандартные функции языка. |
Потеря производительности на геттере - это экономия на спичках. Плюсов же больше:
|
Пример необходимости использования синглтона: |
Одни сплошные минусы для DTO. |
DTO это контейнер для передачи данных, а не доменная сущность. Сущность должна быть всегда валидной, а DTO может быть невалидным и это нормально. |
Пример http://design-pattern.ru/patterns/data-transfer-object.html
7.4 недавно только вышел, более менее стабилным он станет с 7.4.2
аргументируйте
Можно, правда поведение их ни как не настроить, а в тестах это полезно.
Конечно не доменная сущность. DTO по граничным данным может быть не валиден, но вот по типам - очень даже желательно. Если этого нет - в DTO нет особого смысла, массивы полностью решают те же задачи. |
https://github.com/marc-mabe/php-enum/ - тут обычные ValueObject, статика тут не нужна в принципе. У вас есть список констант, константой же можно описать значение по умолчанию, либо вообще ее как значение по умолчанию в конструктор запихнуть, а приватным свойством - текущее значение. https://github.com/gpslab/enum - если честно я вообще не понимаю, зачем нужен этот проект, если SplEnum достаточно. То, что добавили конструкторы по имени и по умолчанию, очень так себе идея, по идее в коде вполне отлично можно обойтись работой только с константами. Если же значение приходит именно как строка откуда-то там из вне то как раз для источника стоит сделать свой кастомный маппер из скопа строк к константам, потому, что источником может быть несколько разных и маппинги потребуются тоже разные. |
У DTO не должно быть поведения. Вы о чем?
Так DTO это расширенная форма массива. DTO отличается от массива только тем, что имеет фиксированную структуру и клиент имеет представление по крайней мере о структуре приходящих ему данных, в отличии от массива. Вы же не имеете контроля за типами данных в массиве, почему тогда ожидаете этого от DTO. |
полностью согласен с @peter-gribanov. class SomeDTO
{
private int $prop;
/**
* @return Свойство, имеющее определенный смысл.
*/
public function getProp(): int
{
return $this->prop;
}
/**
* @param int $prop Задать свойство, имеющее определенный смысл.
*/
public function setProp(int $prop): void
{
$this->prop = $prop;
}
} Хорошо: class SomeDTO
{
/** @var int Свойство, имеющее определенный смысл */
public int $prop;
} код намного лаконичнее - не содержит ничего лишнего.
это из того, что на вскидку пришло в голову. |
Почему же? В случае добавления этих методов у вас появляется интерфейс.
Конкретно в этом случае dto согласен.
Аргумент удачен только для мутабельных dto.
Верно, и будет поставлен в угол на гречку в процессе code review. Если процесс разработки не включает подобный контроль качества, в этих соглашениях смысла может и не быть вовсе.
Достигается это за счет защиты кода.
Это проблема?)) Еще есть wither-ы. Которые вы ни как не реализуете с помощью параметра доступа. Бывают иммутабельные dto, для которых сеттеры не создаются, а все данные заливаются в конструкторе. Ваш пример dto без геттеров для части проектов валиден, при использовании php7.4. Версия 7.3, без поддержки типизированных свойств будет поддерживаться до 6 Декабря 2021. Как минимум я не могу включить это правило по этой причине, так же в данный момент поддерживается еще и 7.2. Исходя из этих рассуждений по моему самый корректный выход - это дополнительные соглашения в проекте, опирающиеся на ЗС, описывающие конкретные паттерны реализации для шаблонных задач. З.Ы. 7.4 только вышел, я бы не рекомендовал сломя голову переходить на него. Лучше подождать пару минорных обновлений с багфиксами и уже после этого пробовать обновляться. |
это уже оффтоп, конечно, но имхо, если какой-то проект не работает в новой стабильной версии php - значит там использована какая-то такая кривота, которую надо выкосить, и чем раньше тем лучше. я думаю, если придерживаться весьма строгих правил из этого списка - подобных проблем не будет в принципе. |
пришло в голову несколько мыслей, поэтому осмелюсь продолжить дискуссию. итак, о DTO. // плохо
class SomeClass
{
public function someMethod($required1, $reqired2, $optional3 = null, $optional4 = 'some', $optional5 = 'other', $optional6 = 'yet another', $optional7 = null, $someVeryImportantOption = 10)
{
// some body.
}
}
$some = new SomeClass();
$some->someMethod(1, 2, null, 'some', 'other', 'yet another', null, 10)
// ай ты блин, мне нужно поменять параметр someVeryImportantOption , адовый адище, капец, одни мысли, и те матом, кто эту либу такую написал. то же самое актуально и для конструкторов. конструкто - тоже метод. длинный список аргументов - это запах. а такой код, как выше - это не просто запах. это вонища. между тем - есть реальный пример, очень даже серьезной либы, именно такой: вот, amqpLib итак - начинаем превращать этот кошмар во что-то поадекватнее: шаг 1. // чуть лучше, но тоже плоховато
class SomeClass
{
public function someMethod(array $configuration = null)
{
if ($configuration === null) {
$configuration = ['some' => 'default', 'configuration'];
// не буду продолжать, я думаю понятно, о чем речь.
}
// some body.
}
} уже намного лучше - задаем в массиве только то, что надо. остальное автоматически берется по-умолчанию. НО. а что там, в массиве-то? ах ты ж.... опять забыл. лезу в документацию. и это хорошо, если есть описание метода. а очень часто его нет. в той же amqpLib нет пхпдоков. короче - время, силы, телодвижения. шаг 3. добавляем ООП. делаем хорошо. class SomeClassConfiguration
{
/** важный параметр, несущий такой то смысл */
public $required1;
/** важный параметр номер два. его смысл - такой то. */
public $required2;
/** и т д, думаю понятно о чем речь. */
public $optional3
public function __construct($required1, $required2)
{
// тут я думаю тоже понято что.
}
public static function createFromArray($required1, $required2, array $otpional)
{
// приблизительная реализация для удобства, чтобы не городить портянку присваиваний.
}
}
class SomeClass
{
public function someMethod(?SomeClassConfiguration $configuration = null)
{
if ($configuration === null) {
$configuration = new SomeClassConfiguration('required1 default', 'req 2 def');
}
// тут тоже все ясно.
}
} вот приблизительно что-то такое и имелось ввиду под DTO. итак, вопросы:
пара слов о static: $some = SomeHelper::some(1, 2, 3);
// или
$some = (new SomeHepler())->some(1, 2, 3); казалось бы, не велика разница.... ну да. не велика. но подзадалбывает писать лишний код, скобки все эти городить... код должен писаться легко, быстро, с удовольствием. к чему это я все:
вы, конечно же, найдете массу контраргументов. похоже мы несколько по-разному представляем себе разработку. что ж... возможно я не прав. все это - мое ИМХО. но не я один так думаю... насколько я понял, этот проект нацелен на создание универсальных принципов для борьбы со сложностью, т.е. для чистого кода, чистой архитектуры, в первую очередь. возможно, следует чуть снизить категоричность? например - не писать public - ЗАПРЕЩЕНО, static - ЗАПРЕЩЕНО. может стоит написать НЕ СЛЕДУЕТ, хотя бы? поверьте мне - придут другие люди, и установят свои правила... удобные правила. я не раз замечал такое - один тимлид гнет свою линию, задалбывает на ревью, приходится по 20 коммитов по началу писать дополнительно, чтобы ему угодить. потом срабатываемся, привыкаем.... а потом - приходит другой тимлид. и что же? "это все говно. будем переписывать". со своим "томиком правил". других правил.... мы же не хотим быть одним из таких тимлидов-самодуров? мы хотим чтобы было правда лучше, легче, проще, удобнее, не так ли? |
Смысл в том, что DTO может спокойно путешествовать через кучу сервисов, при этом сервисы не должны его менять. Вот вам пример, PSR-7 https://www.php-fig.org/psr/psr-7/
Нет общего понятия "по-нормальному" и "по-задротски". Для многих ситуаций действительно
Вы забыли про безопасность и тестируемость.
Сложность кода намного меньше зависит от объема, чем вы считаете. Поверьте, экономия на геттерах - это экономия на спичках.
Она не так хороша, как вы думаете. D из SOLID создан не просто так.
Очень выборочно, многие возможности на лонг ране вылазят боком. Вы же не агитируете за global например, или за eval, или за подстановку параметров в sql через конкатенацию (ну я надеюсь на это). А это все вполне возможности языка.
Понимаете какая штука, судить о реальной краткости и элегантности можно только на протяжении длительного периода после того, как ваш код написан. В момент написания - это только гипотеза.
Увы. Судя по моему опыту, чем крупнее проект, тем жестче должны быть требования, а так же чем ниже экспертиза инженеров - тем жестче должны быть требования.
Да я ж не против, более того данный свод рекомендаций - это основа для конечных договоренностей в конкретном проекте. Вот пример: вы решили, что конкретно в вашем PorjectName нужны DTO на публичных свойствах, а в остальном мои рекомендации вам подходят, да не вопрос, создаете документ CONTRIBUTING.md и пишете в нем, юзаем такие-то правила, в виде исключения для DTO используем публичные свойства.
Такое увы бывает. Если ТЛ не может вам объяснить причину каждого пункта своих правил - это очень печально. Более печально, когда ему все равно.
Я рассуждал так же более 5 лет назад. Жаль что не было человека, который сформулирует мне следующее: простота кода бывает в текущий момент и на длительной эксплуатации, первое может сэкономить день, второе - месяц. Вот эти рекомендации про второе, а не про первое. З.Ы. Пруф https://3v4l.org/WQk7Q В случае |
@alexgivi Я исхожу в своих утверждениях из следующего эмпирического правила: ваш код будет использоваться не правильно. Это очень частая проблема. Меняются требования, или используется косвенная функциональность, не важно, это будет происходить. Ограничения, которые вводятся данными рекомендациями во многом решают эту проблему. |
вообще, PSR7 message вроде как не имеет отношения к DTO. DTO - это структура. это замена безликого массива / stdClass на класс с понятной структурой (хотя бы). |
Вообще говоря по хорошему ассоциативные массивы по возможности лучше не использовать. stdClass - не использовать вовсе.
Тесты это не только способ подтверждения, что что-то работает, это своего рода обратный слепок вашего кода. По хорошему, когда вы меняете код, ваши тесты должны упасть.
Вы сильно преувеличиваете. Тесты для геттеров сеттеров - отлично копипастятся, вопрос пары минут. Что касается клиентов к API тут тоже код как правило шаблонный.
Конечно же не под все)). Чем меньше проект - тем меньший профит будут давать эти правила.
Отличный поинт, добавил таску для этого
Эм... если на проекте изменения возникают редко - это уже похоже на фазу саппорт проекта, а не на активную разработку.
Тип процесса водопад/скрам/... не особо влияет, размер команды тоже. Очень влияет: требования бизнеса к качеству кодовой базы. Грубо говоря, если бизнесу плевать на то, что система может лежать раз в неделю - в этих рекомендациях нет смысла. |
3.4. Модификаторы доступа для свойств
Очень странно, что вы игнорируете часть стандартных функций языка без которых нельзя сделать некоторые вещи.
The text was updated successfully, but these errors were encountered: