Skip to content
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

Open
peter-gribanov opened this issue Dec 20, 2019 · 19 comments
Open

Comments

@peter-gribanov
Copy link

3.4. Модификаторы доступа для свойств

Очень странно, что вы игнорируете часть стандартных функций языка без которых нельзя сделать некоторые вещи.

@index0h
Copy link
Owner

index0h commented Dec 20, 2019

eval, goto, global - тоже стандартная часть языка...))

Можете привести пример?

UPD

Если вы про статику - это способ защиты от выстрела себе в ногу. Если без статики вот ну вообще никак - можно воспользоваться "Здравым Смыслом". Но это очень плохой маячок, вероятно архитектура спроектирована не качественно.

Если вы про public - это в принципе вопрос безопасности, я в курсе по 7.4, такой позволяет защититься как от в принципе не валидных данных, так и дает контроль над доступом к этим данным.

@peter-gribanov
Copy link
Author

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

Синглтон хоть и антипаттерн, но есть кейсы где он необходим. Как и для goto есть кейсы.

@index0h
Copy link
Owner

index0h commented Dec 20, 2019

С DTO нет никаких проблем, да с геттерами и сеттерами.
С синглтоном - я не спорю, возможно, хоть и плохо, для этого стоит использовать ЗС.
На счет крупных постоянных данных, не впихиваемых в константы - кейс действительно возможен. Обычно обходится приватным свойством и геттером, для одного инстанса. Для множества инстансов - в принципе можно вытянуть эти данные в отдельный класс и через DI пробрасывать его. Если вообще вообще никак - опять же ЗС.

@peter-gribanov
Copy link
Author

никаких проблем, да с геттерами и сеттерами.
Обычно обходится приватным свойством и геттером, для одного инстанса.

И получаем потерю в производительности и ухудшение читаемости на ровном месте только из того, что проигнорировали стандартные функции языка.

@index0h
Copy link
Owner

index0h commented Dec 20, 2019

И получаем потерю в производительности и ухудшение читаемости на ровном месте только из того, что проигнорировали стандартные функции языка.

Потеря производительности на геттере - это экономия на спичках. Плюсов же больше:

  1. Валидация типа (до 7.4)
  2. Контроль доступа
  3. DTO можно передавать по интерфейсу.
  4. Методы можно замокать для unit тестов.

@peter-gribanov
Copy link
Author

peter-gribanov commented Dec 20, 2019

Пример необходимости использования синглтона:

@peter-gribanov
Copy link
Author

  1. Валидация типа (до 7.4)
    Не нужно для DTO и не актуально с PHP 7.4
  2. Контроль доступа
    Не нужно для DTO
  3. DTO можно передавать по интерфейсу.
    DTO не должен использовать интерфейс.
  4. Методы можно замокать для unit тестов.
    Свойства можно заполнить и не придется мокать

Одни сплошные минусы для DTO.

@peter-gribanov
Copy link
Author

DTO это контейнер для передачи данных, а не доменная сущность. Сущность должна быть всегда валидной, а DTO может быть невалидным и это нормально.

@index0h
Copy link
Owner

index0h commented Dec 20, 2019

Валидация типа (до 7.4)
Не нужно для DTO

Пример http://design-pattern.ru/patterns/data-transfer-object.html
Вижу упоминание типа для каждого свойства

не актуально с PHP 7.4

7.4 недавно только вышел, более менее стабилным он станет с 7.4.2

DTO не должен использовать интерфейс.

аргументируйте

Свойства можно заполнить и не придется мокать

Можно, правда поведение их ни как не настроить, а в тестах это полезно.

DTO это контейнер для передачи данных, а не доменная сущность.

Конечно не доменная сущность. DTO по граничным данным может быть не валиден, но вот по типам - очень даже желательно. Если этого нет - в DTO нет особого смысла, массивы полностью решают те же задачи.

@index0h
Copy link
Owner

index0h commented Dec 20, 2019

https://github.com/marc-mabe/php-enum/ - тут обычные ValueObject, статика тут не нужна в принципе. У вас есть список констант, константой же можно описать значение по умолчанию, либо вообще ее как значение по умолчанию в конструктор запихнуть, а приватным свойством - текущее значение.
https://github.com/antanas-arvasevicius/enumerable-type - тут то же самое, что и предыдущего.

https://github.com/gpslab/enum - если честно я вообще не понимаю, зачем нужен этот проект, если SplEnum достаточно. То, что добавили конструкторы по имени и по умолчанию, очень так себе идея, по идее в коде вполне отлично можно обойтись работой только с константами. Если же значение приходит именно как строка откуда-то там из вне то как раз для источника стоит сделать свой кастомный маппер из скопа строк к константам, потому, что источником может быть несколько разных и маппинги потребуются тоже разные.

@peter-gribanov
Copy link
Author

Можно, правда поведение их ни как не настроить, а в тестах это полезно.

У DTO не должно быть поведения. Вы о чем?

Если этого нет - в DTO нет особого смысла, массивы полностью решают те же задачи.

Так DTO это расширенная форма массива. DTO отличается от массива только тем, что имеет фиксированную структуру и клиент имеет представление по крайней мере о структуре приходящих ему данных, в отличии от массива. Вы же не имеете контроля за типами данных в массиве, почему тогда ожидаете этого от DTO.
DTO это контейнер формализующий структуру данных и не отвечает за сами данные.

@alexgivi
Copy link

alexgivi commented Jan 3, 2020

полностью согласен с @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;
}

код намного лаконичнее - не содержит ничего лишнего.
аргументация:

  1. если есть закрытое свойство, и для него открытый геттер и открытый сеттер, в которых нет никакой доп. логики - то нет никакого смысла и преимущества их заводить.
  2. код намного короче, и натыкаясь на такой код когнитивная нагрузка существенно ниже. код просто понятнее, а понятность - это важнейшее свойство "чистого кода".
  3. меньше времени на чтение и писание такого кода. разработка идет быстрее.
  4. меньше кода нуждается в поддержке.
  5. чем меньше членов у класса - тем лучше. внешне 1 свойство выигрывает у 2 методов.
  6. речь о коде проекта, который доступен для изменений. private можно превратить в protected и public без проблем, и если кому-то это понадобится, чтобы быстро через костыль решить задачу - он это сделает. так что смысл защищать код от самого себя - весьма туманен...
  7. геттеры и сеттеры отделяются от свойств. получается в объекте код, относящийся к одному атрибуту, разнесен по разным частям класса.

это из того, что на вскидку пришло в голову.
конечно, можно привести аргументы в защиту приватных свойств с геттерами и сеттерами (для ДТО, т.е. когда нет логики) - но ИМХО KISS в данном случае и есть здравый смысл.

@index0h
Copy link
Owner

index0h commented Jan 4, 2020

@alexgivi

если есть закрытое свойство, и для него открытый геттер и открытый сеттер, в которых нет никакой доп. логики - то нет никакого смысла и преимущества их заводить.

Почему же? В случае добавления этих методов у вас появляется интерфейс.

код намного короче, и натыкаясь на такой код когнитивная нагрузка существенно ниже. код просто понятнее, а понятность - это важнейшее свойство "чистого кода".

Конкретно в этом случае dto согласен.

чем меньше членов у класса - тем лучше. внешне 1 свойство выигрывает у 2 методов.

Аргумент удачен только для мутабельных dto.

private можно превратить в protected и public без проблем, и если кому-то это понадобится, чтобы быстро через костыль решить задачу - он это сделает.

Верно, и будет поставлен в угол на гречку в процессе code review. Если процесс разработки не включает подобный контроль качества, в этих соглашениях смысла может и не быть вовсе.

так что смысл защищать код от самого себя - весьма туманен...

Цель данных рекомендаций — снижение сложности восприятия, поддержки, тестирования и расширения кода, написанного разными авторами

Достигается это за счет защиты кода.

геттеры и сеттеры отделяются от свойств. получается в объекте код, относящийся к одному атрибуту, разнесен по разным частям класса.

Это проблема?)) Еще есть wither-ы. Которые вы ни как не реализуете с помощью параметра доступа. Бывают иммутабельные dto, для которых сеттеры не создаются, а все данные заливаются в конструкторе.
Разделение приватные методы например тоже разбрасывают логику по разными местам.


Ваш пример dto без геттеров для части проектов валиден, при использовании php7.4. Версия 7.3, без поддержки типизированных свойств будет поддерживаться до 6 Декабря 2021. Как минимум я не могу включить это правило по этой причине, так же в данный момент поддерживается еще и 7.2.
Так же я не могу включить это правило потому, что паттерн dto не требует конкретно ваш пример реализации, геттеры с сеттерами - это вполне рабочая и корректная альтернатива.
Бывают задачи, в которых необходимо реализовать иммутабельность, для них сеттеры отсутствуют в принципе.

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

З.Ы. 7.4 только вышел, я бы не рекомендовал сломя голову переходить на него. Лучше подождать пару минорных обновлений с багфиксами и уже после этого пробовать обновляться.

@alexgivi
Copy link

alexgivi commented Jan 7, 2020

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

@alexgivi
Copy link

alexgivi commented Jan 9, 2020

пришло в голову несколько мыслей, поэтому осмелюсь продолжить дискуссию. итак, о 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.

итак, вопросы:

  1. зачем усложнять класс конфигурации каким-то там интерфейсом, иммутабельностью? смысл в чем? как должен выглядеть интерфейс? каждому классу по интерфейсу? имхо - это уже перебор. зачем этому классу иммутабельность? какие ПОЛЕЗНЫЕ задачи она решает в данном конкретном случае? имхо - "безобразно но единообразно" - единственное, что можно сказать в оправдание такого подхода.
  2. тестируемость, тестируемость... будем мокать геттеры и сеттеры? мне кажется что-то пошло не так в этот момент... надо подумать - и сделать "по-нормальному". не по-задротски, а по-нормальному.
  3. к чему мы стремимся? к простоте. к удобству. к понятности. к легкости использования. к легкости изменения, развития, доработки. чем больше кода - тем сложнее его читать, понимать, тем тупо больше времени надо на это, тем сложнее его исправлять, и тем больше вероятность накосячить при этом. в итоге мы получим проект, который зашел в тупик. дальнейшее развитие требует колоссальных усилий. а если еще и текучка на проекте - так вообще капец. пиши пропало, пока новый человек въедет в эти сотни файлов - уже все дедлайны уплывут.

пара слов о static:
существует такой тип классов - helpers. просто совокупность некоторых полезных функций, относящиеся к чему-либо. StringHepler, ArrayHepler, FilesystemHelper, не важно что. не суть.
что они из себя представляют? набор статических методов, и только их.
иногда часть методов имеют общий функционал. приходится создавать приватные методы, либо просто чтобы метод не был на 150 строк с 10 уровнями вложения циклов и условий. мы же пишем чистый код в 2020, не правда ли? так зачем нам эта legacy-вонь?
"так нафига статик, делай не статик", скажете вы.
"зачем?" отвечу я. это используемая практика, и она ХОРОШАЯ. т.е. удобная, простая, понятная.
что лучше?

$some = SomeHelper::some(1, 2, 3);
// или 
$some = (new SomeHepler())->some(1, 2, 3);

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

к чему это я все:

  1. если в языке есть какие-то возможности - можно и нужно использовать их для борьбы со сложностью - имхо самым главным врагом программиста.
  2. оверинжениринг - это плохо. это мина замедленного действия. если есть возможность сделать кратко и элегантно - надо делать кратко и элегентно. НАДО. искусственно загоняя себя в тяжелые рамки без public и static - мы пилим сук, на котором сидим, роем себе яму.

вы, конечно же, найдете массу контраргументов. похоже мы несколько по-разному представляем себе разработку. что ж... возможно я не прав. все это - мое ИМХО. но не я один так думаю... насколько я понял, этот проект нацелен на создание универсальных принципов для борьбы со сложностью, т.е. для чистого кода, чистой архитектуры, в первую очередь. возможно, следует чуть снизить категоричность? например - не писать public - ЗАПРЕЩЕНО, static - ЗАПРЕЩЕНО. может стоит написать НЕ СЛЕДУЕТ, хотя бы? поверьте мне - придут другие люди, и установят свои правила... удобные правила. я не раз замечал такое - один тимлид гнет свою линию, задалбывает на ревью, приходится по 20 коммитов по началу писать дополнительно, чтобы ему угодить. потом срабатываемся, привыкаем.... а потом - приходит другой тимлид. и что же? "это все говно. будем переписывать". со своим "томиком правил". других правил.... мы же не хотим быть одним из таких тимлидов-самодуров? мы хотим чтобы было правда лучше, легче, проще, удобнее, не так ли?

@index0h
Copy link
Owner

index0h commented Jan 10, 2020

@alexgivi

зачем усложнять класс конфигурации каким-то там интерфейсом, иммутабельностью? смысл в чем?

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

Вот вам пример, PSR-7 https://www.php-fig.org/psr/psr-7/

Messages are considered immutable; all methods that might change state MUST be implemented such that they retain the internal state of the current message and return an instance that contains the changed state.

будем мокать геттеры и сеттеры? мне кажется что-то пошло не так в этот момент... надо подумать - и сделать "по-нормальному". не по-задротски, а по-нормальному.

Нет общего понятия "по-нормальному" и "по-задротски". Для многих ситуаций действительно
достаточно использовать геттер (в сервисе, использующем dto, получая свойство на прямую вы вот вообще ничего не выигрываете). Бывают ситуации, когда нужно мокать и геттеры и сеттеры.

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

Вы забыли про безопасность и тестируемость.
Вредят ли геттеры понятности в коде, который их использует?
Вредят ли геттеры легкости использования?
Что касается легкости изменения, развития, доработки.: вы перегибаете палочку, переименование через Shift+F6 переименует и геттеры и сеттеры, замена типа, или удаление вас не убережет от проверки кода, которые использует то, или иное свойство.

чем больше кода - тем сложнее его читать, понимать, тем тупо больше времени надо на это, тем сложнее его исправлять

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

это используемая практика, и она ХОРОШАЯ. т.е. удобная, простая, понятная.
что лучше?

Она не так хороша, как вы думаете. D из SOLID создан не просто так.
Допустим у вас есть сервис, использующий FilesystemHelper, в чем проблема через конструктор явно указать свойство для этого сервиса? Тестировать так его легко, замокали и радуемся. Заменить на другую реализацию в конкретном случае - тоже легко, задаем другую реализацию FilesystemHelper и радуемся. Как раз с точки зрения поддержки/рефакторинга/расширения кода - это лучший способ.

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

Очень выборочно, многие возможности на лонг ране вылазят боком. Вы же не агитируете за global например, или за eval, или за подстановку параметров в sql через конкатенацию (ну я надеюсь на это). А это все вполне возможности языка.

если есть возможность сделать кратко и элегантно - надо делать кратко и элегентно.

Понимаете какая штука, судить о реальной краткости и элегантности можно только на протяжении длительного периода после того, как ваш код написан. В момент написания - это только гипотеза.
Приведу пример: на прошлой работе для одной из задач мне потребовался сервис, умеющий по всему огромному проекту делать разнообразные мелкие выборки, типа login, дата последнего логина, были ли оплаты, когда последняя оплата и т.д. много много выборок. Сервис не предполагалось использовать еще где либо. Беда была в том, что я недо-бдил с его изоляцией. На проекте помимо меня 600+ инженеров. Через несколько месяцев ко мне начали стучаться инженеры из других отделов с просьбами добавить еще выборок, или подправить под их нужды. На что был резонный ответ: парни вам это нельзя трогать, это внутренняя штука для моего модуля, я ведь поменяю что-то и предупреждать не буду. Мне потом этот сервис еще несколько лет вспоминали. Хотя на момент написания сервис получился отличный.

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

Увы. Судя по моему опыту, чем крупнее проект, тем жестче должны быть требования, а так же чем ниже экспертиза инженеров - тем жестче должны быть требования.

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

Да я ж не против, более того данный свод рекомендаций - это основа для конечных договоренностей в конкретном проекте. Вот пример: вы решили, что конкретно в вашем PorjectName нужны DTO на публичных свойствах, а в остальном мои рекомендации вам подходят, да не вопрос, создаете документ CONTRIBUTING.md и пишете в нем, юзаем такие-то правила, в виде исключения для DTO используем публичные свойства.

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

Такое увы бывает. Если ТЛ не может вам объяснить причину каждого пункта своих правил - это очень печально. Более печально, когда ему все равно.

мы же не хотим быть одним из таких тимлидов-самодуров? мы хотим чтобы было правда лучше, легче, проще, удобнее, не так ли?

Я рассуждал так же более 5 лет назад. Жаль что не было человека, который сформулирует мне следующее: простота кода бывает в текущий момент и на длительной эксплуатации, первое может сэкономить день, второе - месяц. Вот эти рекомендации про второе, а не про первое.

З.Ы. is_null($configuration) быстрее чем $configuration === null

Пруф https://3v4l.org/WQk7Q
На сколько я понял по op кодам https://3v4l.org/cq2aN/vld#output

В случае $value === null сравнивается И значение И тип.
В случае is_null($value) сравнивается только тип.

@index0h
Copy link
Owner

index0h commented Jan 10, 2020

@alexgivi Я исхожу в своих утверждениях из следующего эмпирического правила: ваш код будет использоваться не правильно. Это очень частая проблема. Меняются требования, или используется косвенная функциональность, не важно, это будет происходить. Ограничения, которые вводятся данными рекомендациями во многом решают эту проблему.
Если поменять требования к свойствам и методам на РЕКОМЕНДУЕТСЯ, сразу возникает момент, это не обязательно.
Допустим вам сейчас удобно заюзать публичное статическое свойство которое создается один раз, другому инженеру для его задачи надо будет его поменять, в вашей же задаче оно меняться не должно... было не должно и даже не менялось на протяжении года. Тестами все отлично покрыто, каждый тест чистит состояние до и после себя. И тут в один прекрасный релиз ваш функционал тупо отваливается с не ожидаемой плавающей ошибкой, которую qa не отловили. На поиск и устранение вы можете потратить кучу времени. Фактически вам уже надо поправить две таски: свою и чужую.

@alexgivi
Copy link

вообще, PSR7 message вроде как не имеет отношения к DTO. DTO - это структура. это замена безликого массива / stdClass на класс с понятной структурой (хотя бы).
конечно, можно реализовать fluent setters, и иммутабельность типа withParam1($param1): self, и т д. даже наверное хорошее решение получится. но изначально замысел был в том, чтобы сделать структуру явной, только и всего. давайте тогда запретим использовать в коде ассоциативные массивы с ключами-строками, и StdClass. ведь они вообще никак не защищены, от слова совсем. намного хуже чем некий класс.
да, безопасность и тестируемость, несомненно, важно, но "тестируемость ради тестируемости" тоже может быть излишней. покрывать каждый метод - каждый ничего не подразумевающий геттер и сеттер структурки - ну это просто куча труда впустую. особенно, если структура огромная, и часто меняющаяся во времени. в различных системах-агрегаторах, работающих с разными сторонними API это ситуация частая.
а вообще - да, я согласен, что чистый ООП подход - лучший. конечно в языке не хватает многих удобных плюшек, как в C# например... на часть из них были RFC (например вот), но сообщество отклонило эту идею. что ж, значит придется продолжать использовать костыли на ассоциативных массивах, фабрики с fluent setter-ами, и т д.
в целом, для "на всю голову enterprise" проектов, правда, максимальная строгость необходима, некоторые же проекты, наоборот, подразумевают гибкость и быстроту модификации главными ценностями, одним словом этот свод правил не подо все проекты. пожалуй сойдемся на этом, думаю имело бы смысл добавить секцию "введения", где описать общую философию подхода, и т д. чтобы люди сразу понимали, о чем речь, к каким проектам данные правила применимы, а к каким не следует их применять. например, для короткосрочного проекта, для проекта, где скорость внедрения новых фич важнее безопасности, для проекта, где изменения возникают очень часто - следование этим правилам просто загонит разработку в тупик. это подходит для серьезных, формальных проектов, с водопадным подходом к разработке, с огромной командой, с длительными сроками...

@index0h
Copy link
Owner

index0h commented Jan 10, 2020

@alexgivi

давайте тогда запретим использовать в коде ассоциативные массивы с ключами-строками, и StdClass

Вообще говоря по хорошему ассоциативные массивы по возможности лучше не использовать. stdClass - не использовать вовсе.

покрывать каждый метод - каждый ничего не подразумевающий геттер и сеттер структурки - ну это просто куча труда впустую.

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

особенно, если структура огромная, и часто меняющаяся во времени. в различных системах-агрегаторах, работающих с разными сторонними API это ситуация частая.

Вы сильно преувеличиваете. Тесты для геттеров сеттеров - отлично копипастятся, вопрос пары минут. Что касается клиентов к API тут тоже код как правило шаблонный.

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

Конечно же не под все)). Чем меньше проект - тем меньший профит будут давать эти правила.
Грубо говоря, если ваш проект на несколько месяцев - нет смысла придерживаться подобных требований, ну разве что выбрать самые не напряжные.
Если команда прям прониклась Laravel/CodeIgniter/... часть этих требований будут вредными и сожрут кучу времени, просто потому что придется воевать с фреймворками.

думаю имело бы смысл добавить секцию "введения", где описать общую философию подхода, и т д. чтобы люди сразу понимали, о чем речь, к каким проектам данные правила применимы, а к каким не следует их применять.

Отличный поинт, добавил таску для этого

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

Эм... если на проекте изменения возникают редко - это уже похоже на фазу саппорт проекта, а не на активную разработку.

это подходит для серьезных, формальных проектов, с водопадным подходом к разработке, с огромной командой, с длительными сроками...

Тип процесса водопад/скрам/... не особо влияет, размер команды тоже. Очень влияет: требования бизнеса к качеству кодовой базы. Грубо говоря, если бизнесу плевать на то, что система может лежать раз в неделю - в этих рекомендациях нет смысла.
Когда бизнесу критичны такие штуки, как диплой без даунтайма, круглосуточная поддержка, когда даже за 1% прибыли идет борьба - вот в таких случаях эти требования выстреливают.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants