Как стать автором
Обновить

Комментарии 101

Однажды наткнулся на другую сторону строгой типизации — системы, которые позволяют вместо одного класса-обработчика подставить другой, как например Magento. Написал функции которые принимали параметры заданного типа (к примеру func(Mage_Catalog_Model_Product $product)), но вот я не учел, что класс подменили на другой стороннего модуля, и лог сразу засорился предупреждениями о несоответствии типов. Пришлось всюду убрать любую типизацию входных параметров и проверку на тип переменных.
Этот стороний модуль должен наследовать Ваш класс, и всё будет ок, иначе получилось нарушение наследования, у вас 2 разных класа с одинаковым целевым применением.
А зря. Даже если не получалось наследовать базовый класс, можно было бы хотя имплементировать одинаковый интерфейс.
Наследовать для чего? Если мне нужно обработать продукты, а не изменить логику их работы, мне незачем наследовать базовый класс. Если наследовать его внутри модуля, не перезаписывая на уровне системы, только чтобы иметь возможность посылаться на этот тип, а потом установить другой модуль который перезаписывает модель, я буду наследоваться от класса, который не стоит первым в цепочке. Вариант же, когда я перепишу класс Продукт на уровне системы, только ради типизации, бредовый — можно запросто перетереть уже установленный сторонний. С какой стороны не посмотри, куча минусов от людей, которые просто не в теме.
Не недо читать php для начинающих.:((((
Я бы порекомендовал читать еще что-то кроме нее.
$eventData->arguments = array('id' => 15);

В конечном итоге, остался массив, структура которого неведома. Должно было быть что то типа
$eventData->arguments = new EventData_Arguments(15);
Продолжая улучшать наш пример, я бы не остановился на создании одного класса. Обычно в современных веб-приложениях происходит много различных событий, и в них передаются разные аргументы, их можно сгруппировать, и для каждой группы событий создать свой — подходящий класс аргументов.


Вот в этом абзаце я об этом и пытался сказать, видимо не очень понятно получилось.

Т.е. предполагается что есть события в которых нужен $id, а есть события в которых нужен, скажем, какой ни будь $templateKey.

Эти события можно определить в две группы, скажем DocumentEvents и TemplateEvents, и создать для них два класса аргументов наследующихся от базового EventsArguments.

Соответственно в функциях-хендлерах в тайп хинтинге мы указываем эти классы, и соответсвенно при работе с ними у нас не возникает вопросов, что там приходит в параметрах.
Это конечно очень и очень круто и я стремлюсь к этому, но уж очень напрягает плодить отдельный класс для каждого массива. Всё это порождает другие сложности. Я бы назвал их «бюрократическими».

//Эта конструкция говорит парсеру, что будет возвращен массив, состоящий из объектов этого класса

И если уж говорить о совсем строгой типизации, то здесь нужно делать коллекцию. Таким образом, для таблицы `users`, потребуется создать минимум два класса User + UsersCollection. Ну и ещё в класс User добавить геттеры+сеттеры для всех 22 полей. А при добавлении нового поля в таблицу, нужно не забыть добавить новое поле+геттеры+сеттеры в класс User. Это напоминает бюрократические походы в 100500 энстанций, вместо того что бы просто сделать один ALTER TABLE.
Зачем, же? например в том же самом Magento, геттеры и сеттеры реализованы через __call,
если нам нужно добавить параметр в какойнибудь обьект, просто делаем

$obj->setSampleKey(«SampleVar»);
$obj->getSamleVar();

__call же, берёт первые три буквы метода, и соответственно отправляет данные на __get или __set для подальшей обработки.
магические методы тоже имеют свои минусы. Не зря их называют «магическими».
Конкретно в Мадженте это костыль вокруг getData/setData, и они сами планировали отказаться от магии.
… и, в конце концов, Magento — не истина в последней инстанции.
Все верно, такая структура позволит вам быть чуть более уверенным в том что нигде ничего не поломается со временем, и уверенным в том, что в любой момент вы сможете добавить некую бизнес логику в сеттер поля Name.

Часто «быстрые» решения не всегда полезные. Иногда приходится тратить несколько часов на рефакторинг определенного кода, хотя это можно за 2 минуты решить с помощью копипаста одной функции в несколько мест. Цена этого решения всплывет потом, и смею вас уверить будет гораздо дороже чем изначально придерживаться принципов заложенных архитектурой.
Я не имею ввиду что это сложно. Я имею ввиду что это хрупко. Если не мне а другому программисту потребуется добавить новое поле, он сделает ALTER TABLE, но вспомнит ли он про новое поле в User?

Сдаётся мне, что если у вас есть не самый большой проект состоящий из 50 таблиц, в каждой из которых, в среднем, по 10 полей (всего 500 полей), то поддерживать в актуальном состоянии 100 классов и 1000 методов (сеттеры+геттеры) будет не то что бы накладно, а очень хрупко. Особенно если над проектом работаете не только Вы один.
Для этого есть IDE или генераторы кода. Возьмем Doctrine 2 и описание маппинга в yml/xml:
  • Добавили описание поля
  • Запустили генерацию кода сущностей (автоматически добавилось поле, геттер, сеттер, инициализация коллекции в конструктор, если нужно) — doctrine:generate:entities
  • Запустили обновление схемы БД — doctrine:schema:update
Если вы собираетесь модифицировать классы (добавлять новые методы или модифицировать геттеры/сетторы), то перегенерацию кода лучше не использовать. А если вы не собираетесь модифицировать классы, то в чём профит? Только в автодополнении?
Doctrine к сторонним изменениям относится бережно — добавление геттеров-сеттеров инкрементальное (имеющиеся геттеры и сеттеры не изменяются, сторонние методы тоже, новые пишутся в конец класса), бэкап старого файла с классом делается автоматически. IDE подствечивает отличия от текущей ревизии VCS, всегда можно в этом убедиться после генерации. Проблем с модификацией классов сущностей и параллельным добавлением новых полей с помощью генерации кода нет.
Это интересно. Но не все пользуются Doctrine.
Безусловно, я привел ее именно как пример удобного инструмента, из которого можно почерпнуть наработки по автоматизации рутины.
$eventData = array(
'sender' => $controller, //экземпляр некоего контроллера
'name' => 'onDelete',
'group' => 'global',
'arguments' => array(
'id' => 15
),
);

По моему достаточно для комфортной работы использовать геттеры и сеттеры. И дополнять PHPdoc @property. Например: @property BaseController $sender
Насчет строгой типизации — поддерживаю, сам в последнее время стал использовать.
Посыл статьи правильный, но, ИМХО, не те вопросы, не тем инстурментом, есть тесты, которые выполняют две очень важные в разработке вещи — проверяют правильно ли вы вычисляете значения и одновременно документируют ваш код. Если код и тесты написаны криво, что ж это скорее беда программиста, которую к сожалению ни один язык не исправит — ни строго типизированный ни динамически.
И к слову сказать, если вам так нравится ООП и нравится, что везде вместо обычных типов — классы, которые можно расширять — обратите свое внимание на Ruby, как минимум вам не придется изобретать велосипед, как максимум вы откроете для себя новый мир.
Лучше Python, там такого безумного количества синтаксиса нет.
Дело вкуса же.

Для меня — в пейтоне безумное количество синтаксиса, избыточное.
Причём тут дело вкуса? Есть объективная реальность. В Руби его действительно намного больше.
Синтаксис один. DSL это всего-лишь бонус, если вы используете гем с извращенным DSL, то это не косяк языка :)
Мы сейчас стандарты сравниваем?
Автор и так осваивает C# )) За исключением ограничения платформы, он ничем не уступит Ruby, Python и тд… (ASP.NET MVC)… Так же постепенно ухожу из РНР в дотНет — ASP.NET MVC безумно радует, шарп + EF + LINQ + WebApi безумно доставляют )

ПыСы: НЕ холивара ради
Хочу заметить что при таком решении количество кода возрастает и также возрастает зависимость от IDE
А ещё возрастут тормоза. Объекты работают медленнее примитивных типов.
Уже надоело видеть это замечание в любом предложении об использовании ООП или большого количества обьектов. В всех проектах тормоза вызваны не ООП и не обьектами, а кривыми руками программистов. Да, использование обьектов дает небольшой перерасход ресурсов, но это не сравнится с какой нибудь сортировкой пузырьком или запросом на 3 таблицы в БД чтобы извлечь значение которое потом нигде не используется.
По поводу «всех проектов» я вам следующее скажу. Мне проходилось далеко не один высоконагруженный проект делать. И в некоторых случаях нужно было прекрасные фантазии с абстрактными базовыми классами и прочим переделывать на обычные массивы. Иногда становилось значительно быстрее.

Добро пожаловать в реальный мир.
В вашем же ответе есть подтверждение моим словам :). Ключевые слова: «некоторых случаях» — «Иногда становилось».

Я не спорю что массивы действительно могут помочь в определенных случаях (например ресурсоемкий алгоритм обрабатывающий десятки тысяч обьектов за раз), но в большинстве случаев разница не принципиальна. Зато правильное использование ООП позволяет сделать поддержку и развите проекта легче и это как правило гораздо важнее 10% выигрыша в производительности.

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

Инструментарием нужно пользоваться с умом и отказываться от совсем уж извращённых конструкций там, где это совершенно не нужно. Например, скрипт-парсер на 5 процедур значительно выиграет в производительности у скрипта с одним классом на 35 методов и в 3 раза раздутым кодом, а для парсера это очень критично.

Поэтому далеко не во всех проектах «тормоза вызваны не ООП и не обьектами, а кривыми руками программистов». Во многих проектах эти же тормоза вызваны использованием неоптимальных подходов к проектированию архитектуры.
Производительность и методикой написания никак не связаны.

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

Не надо быть ежом, чтобы понять, что в определённом узком месте лучше сделать тупо или написать «говно»-код (гОвно имеется в виду не изящный, а оптимизированный добезумия), или вааще переписать на C.
Статические HTML странички отдаются еще быстрее, но ведь никто не стремится делать сайты на одном только HTML?

Нам всегда нужно выбирать между удобством разработки и эффективностью наших программ.

К примеру, тот же ActiveRecord: все знают что он медленнее чем просто запрос-ответ, но так же никто не собирается с него уходить, все понимают какие плюсы он несет. Скорость и удобство разработки, не сопоставимо с теми тормозами которые могу возникнуть.
Про «никто не собирается уходить» я с вами не согласен. Я согласен, что баланс нужно соблюдать. Иногда я выберу ActiveRecords, иногда откажусь от него.

На статичных HTML сайты тоже делают. И много сайтов, которые кешируют себя в статичных HTML.
Делая вывод из вышесказанного, мы можем указывать почти все, кроме скалярных типов, но и на этот счет PHP имеет решение. В стандартной библиотеке SPL, содержится несколько занимательных классов призванных решить эту проблему:
SplInt
SplFloat
SplEnum
SplBool
SplString

Скорее это задел на будущее. Посмотрите на ArrayObject, например. PHP медленно движется к тому, чтобы все типы были объектами. Когда-нибудь PHP совершит переключение. А пока эти объекты будут потихоньку появляться и покрываться нужными методами.
Понятия «правильной архитектуры» и «эффективного программирования» ортогональны обоим упомянутым вам понятиям типизации. Напрасно вы всё это в кучу собрали.
Эффективность обуславливается опытом и инструментами (как на уровня языка, так и уровня сред программирования), а правильность архитектуры вообще эфимерна.

Остается только расценивать вашу статью как обзор phpDoc и typehinting.
ООП головного мозга
А чего минусанули-то? Предлагая заменять повсеместно массивы объектами, автор на самом деле диагностировал у себя ООПухоль лобной доли.
Вы видимо прочитали только заголовки в статье.
Если бы в рассмотрели пример, и вникнули в суть, то поняли, я не предлагаю заменить ВСЕ массивы.

Массивы — это удобный инструмент, и должен использоваться по своему прямому назначению, а именно:

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

(вики)

И в этих случаях они и должны быть использованы.

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

Может быть, я все-таки проглядел, вы тогда процитируйте себя пожалуйста.
Добавил предупреждение. Теперь должна быть понятнее суть предложения.
Отлично! Спасибо.
Не указание чего-либо !== Призыву к чему-либо противному
Инструкция, в которой должным образом не указано как пользоваться инструментом по назначению – плохая инструкция. Автор согласился, а вы поспорить хотите?
Неа.

Просто мы таким образом путаем понятия.

Инструкция плоха — окей. Но вывод из отсутствия некоего утверждения на противоположное — вот что меня покоробило. Да и хрен с ним.
А можно пример, когда массив в php может являться центром всей системы?
В плохо спроектированных ООП системах — сплошь и рядом.

К примеру есть некий контроллер NewsController, есть вроде как даже модель NewsModel (правда в не совсем верном её понимании).

У модели есть метод: NewsModel->getAllNews(), при вызове которого, а возвращается какой то массив, с этим массивом дальше начинают работать в контроллере, всячески его обрабатывая, и в конце концов выводя в браузер.

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

Это cake во всей своей «красе».

Yii в этом отношении лучше, Zend — ещё лучше, а симфони вааще всех за пояс затыкает полнейшим DI.
А может проще тогда заставить записывать метод NewsModel->getAllNews() в переменные класса, вместо возврата массива?

Или сделать возврат вместо массива ссылки на класс, например используя объектный стиль работы с mysqli, вместо процедурного/
Хочу только напомнить, что стандартный массив в php — это сортированный map. Поэтому массивами все часто и пользуются в качестве Value Object-ов.
Так-то оно так, да только это как посмотреть (с) неизвестный рыбак с Ливенки

Представим дядю Васю. Подхожу я к дяде Васе и говорю: подержи, дядя Вася, молоток и забей-ка им пару гвоздей в заборе. Дядя Вася берет молоток, идет и забивает пару гвоздей. Функция работает. Но вот, беру я микроскоп, подхожу к дяде Васе и говорю: дядь Вась, а давай-ка ты вот это возьмешь и забьешь пару гвоздиков вот этим. Ошибка типа, — говорит мне дядя Вася. И приходится мне учить дядю Васю забивать гвозди микроскопом, т.е. писать новую функцию в его сознании. А это — дополнительные затраты на разработку.

Или вот… Подхожу я к дяде Васе и говорю: дядь Вась, отправь почту. И отдаю ему массив: три посылки. Берет и отправляет. Подхожу опять: дядь Вась, вот тут другой массив: две посылки и одно письмо. Отправь, пожалуйста. А он мне: иди ты, мальчик, у тебя массив не такой как я умею. И облом.

Вывод: подсказки и описание назначения и схемы работы функций, входных и выходных данных, конечно, хорошо. Но не следует это путать с типизацией. Хороший правильный дядя Вася должен уметь гвозди забивать всем тяжелым инструментом, что мы ему дадим. И отправлять любую корреспонденцию, какую мы ему вручим, если на ней стоит адрес и ФИО получателя. И не материться, что она не того типа.
Ага, говорите «забей гвоздь дядя Вася». Он берет микроскоп, и хреначит. Не потому что надо, а потому, что все время он доставал из коробки молотки, а тут как-то там появился микроскоп (кто-то в стороне накосячил). И что бы вы думали, дядя Вася не думая расхреначит к хренам микроскопом, или еще лучше, промычит что-то типа «а я не нашел рукоятки и не стал ничего делать», гвоздь останется не забитым, и мы потом будем еще веселиться по поводу того почему каждый 17-ый гвоздь не забит, и микроскопы все разбиты.
Это уже беда другого характера — это отсутствие проверки входных данных. Тоже черта плохого дяди Васи.

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

А вот когда дядя Вася сообщает об ошибке — это правильно. И упоминание характера ошибки — тем более правильно. «Не нашел рукоятки», — точное и корректное сообщение.
Умение мыслить абстрактно — то, что отличает человека от обезьян и проч.

Или даже то — что сделало из обезьяны человека.

ps: Хотя как это оно так сделало?
Это вы к чему?
К тому, что надо в случае конфликта конкретики переходить на абстракцию.
А где вы нашли «конфликт конкретики»? Кстати, что это такое?
Молоток — конкретика1.
Микроскоп — конкретика2.

Конфликт конкретик — ошибка типа.

Что такое интерфейсы мы типа не в курсе. Да в курсе мы! Просто подлая лень нас вечно побеждает. Да или не да? :)
А-а-а. Ви в ентом смисле (с) не вспомню под вечер и на больную голову, из какого фильма

Абстракция — наше все.

Кстати, вспомнил еще кое-что. В PHP еще с 4-ой его версии была хорошая рекомендация вот в этой книжке.

Суть рекомендации сводилась к следующему:
1. документировать
2. проверять входные данные на соответствие задаче
3. выдавать адекватные сообщения при их несоответствии
4. наслаждаться прелестями отсутствия типизации
Эта рекомендация — то же самое, что типизация, только средствами ПХП4.

Цель та же самая, но типизация — это не велосипед.
Не сказал бы, что то же самое.
Отличия:
1. на входе все еще слабо типизированные данные, которые могут нести дополнительную информацию, может, этой самой функции и не нужные, но нужные где-то еще.
2. входные данные, если они имеют дополнительную информацию, могут задействовать дополнительные операции внутри функции.
3. программист, руководствующийся этой рекомендацией, не забывает о дополнительных проверках, которые компилятор просто не в силах осуществить.
Для того, чтобы что-то умело нести что-то нужное где-то еще придумали интерфейсы.

interface bla {
    method foo()
}

class bar impl bla {
   metod foo() {...} // and million other info
}
Массив — упорядоченный набор данных, для хранения данных одного типа, идентифицируемых с помощью одного или нескольких индексов. вики

Фраза «заменить массив объектом» для не-пэхапэшника звучит несколько дико
А зачем использовать PHP, если для ваших нужд необходима статическая типизация? Динамическая типизация — это гибкость и скорость разработки. Превращая PHP в Java вы растеряете все преимущества скриптового языка, при этом не получив преимуществ компилируемых (как например отловка ошибок еще перед тем как вы запустили сам проект или во время компиляции).
Со статической типизацией в IDE хорошо работается. Это скорость и восполнение забывчивости.
В остальном, да, блажь.
Это суровая правда жизни. Желая иметь стабильный софт, но и находить разработчиков которые смогут его поддерживать, приходится писать на строго(иногда почти-строго) типизированном php.
Стабильность софта можно обеспечить тестированием. Необязательно превращать PHP в строго типизированный язык. Ну и Java с .Net никто не отменял. А разработчиков, способных писать хороший код, искать нужно и для PHP.
Я просто говорю о реалиях, за год мы нашли 4 нормальных php разработчика, и только одного хорошего java разработчика (у нас есть и php и java).
.Net это дорогая инфраструктура, да и ide не дешевые.
Тесты это выход, но он куда более трудозатратен чем строгая типизация в коде.
Все таки аренда серверов сейчас уже дешевле чем неделя команды даже из 10 человек.
Тесты это выход, но он куда более трудозатратен чем строгая типизация в коде.

Это Вам ваши PHP'шники нашептали?
Это реалии рынка — «добро пожаловать в реальность» (с)

ПХП — более свободная платформа в отличие от явы (оракл) и сишарпа (мс).

Хотя и ява и оракл лучше пхп в плане того, что они на след. ступеньке развития (статичны, компиляемы и переносимы).
Прошу не трогать наших PHP-шников. Вы ничего не знаете о их способностях, и предвзятое отношение здесь не уместно.

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

Даже для небольших и молодых проектов я сомневаюсь что можно такое утверждать.

Ну и я говорю 300+ мегабайтах кода, трех тысячах тикетов в год (около 30 небольших релизов и 3 крупных).

Backend покрыт тестами, но он не настолько часто меняет поведение.
FYI, это была добрая ирония.
Не хочу вдаваться в холивар. Каждый разрабатывает так, как того требует архитектура и определения «правильно/неправильно» можно давать только относительно каждого проекта/задачи, но не в рамках всего языка.
FYI, это была добрая ирония.

Тогда прошу прощения.

На самом деле я люблю тесты. И на самом деле мы пытаемся их внедрять, потому как сложные части таки необходимо покрывать тестами.
Но получается покрывать далеко не все.
Во второй симфони есть очень интересный компонент, который позволяет валидировать массивы параметров:
github.com/symfony/OptionsResolver
Фишка не в валидации, а в IDE`шке.

+ такой велосипед на то, что встроено не есть хорошо. Хотя возможно в какой-то ситуации хорош.
Нет, фишка как раз таки в валидации. Компонент позволяет не создавать на каждый чих value-object в параметрами + ещё имеет огромную кучу плюх. Посмотрите пример в документации хотя бы
github.com/symfony/OptionsResolver/blob/master/README.md
Я имею в виду фишка призыва к объектам — больше пользы в code-completeion`е.

Код пишется один раз, а читается, обновляется тыщщи.

+ и там и там нам надо будет код писать — что новый класс, что новый конфиг опций.

Создать файл нового класса — это не всегда страшно :) Да и пусть они лежат где-нить в одном месте, чтобы зайти туда и сделать Ctrl+C / Ctrl+V.

Я тоже иногда ленюсь классы делать, но тут уж не инструменты, а воля больше должна работать.
А ещё есть такие моменты как:
1. Валидация значений (например поле gender — только 'male' или 'female')
2. Динамические параметры по умолчанию — вот это самый главный плюс компонента. Это когда если один из параметров не передан явно, то на основе других параметров можно вычислить его значение.

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

<?php

class Foo {

/**
 * @var string Some thing
 */
private $_someThing = 'bar';

}


ps: Простите, не удержался :)
Хочу подметить (как однажды подмечал уж), что все три языка, наиболее популярные в сайтостроении (JavaScript, PHP, а до PHP — Perl), имеют динамическую слабую неявную типизацию.

Стало быть, что-то в этом есть, не правда ли?
Если это есть — не значит, что это хорошо. Сигареты вон везде продаются, а от курения люди умирают.
Перефразируя: зимой выпадает снег, но это не значит, что это хорошо.
Это просто есть. И раз уж это один из слонов, на которых стоит PHP, то зачем под него засовывать дополнительные костыли?
Снег — это прекрасно. Снежки, горные лыжи и снеговики за него. А уж дед мороз без него к нам не доедет.

Однако вернёмся к нашим боратам — если что-то просто есть и это слон, то не значит, что стоя на слоне мы делаем хорошо. На слоне надо ездить и желательно в повозке с опахалом.

Вот эта повозка и есть.

Сравните просто лошадь и лошадь с седлом — какая лучше?

Седло !== Костыли.
Седло от лошади не совместимо со слоном.

P.S. Я не говорю, что статическая типизация — плохо. Просто возникают сомнения в адекватности подхода, описанного в статье.
Мне почему-то для контроля типов достаточно PHPDoc и строгой проверки там, где это критично.
Методу человек.СидетьНаСедле(АбстрактноеСедло $седло) это пофигу, т.к. используется такое понятие, как абстракция.

Слон вааще с лошадью не совместимы и че?
Сам PHP развивается все больше в сторону OOP, предлагая все больше инструментов для этого. В этом тоже что-то есть. Да и в JavaScript прекрасно можно работать с объектами, что зачастую сильно упрощает работу с ним.

С автором могу только согласиться, что видишь PHP немного по-другому, поработав со строго типизированными языками типа Java, C#, Obj-C.
>> Стало быть, что-то в этом есть, не правда ли?
Думаю, что низкий порог вхождения и большая скорость разработки и делает привлекательным именно этот подход.

Однако как многие профессионалы в своё время отказались от Windows и пересели на более надёжный и предсказуемый Linux. Так эти же люди со временем предпочтут более строгий язык, но чуть надёжный язык.
Разрабатывая плагины под Livestreet столкнулся и взял на вооружение следующую практику. Имя каждой переменной начинается с буквы, которая обозначает тип данных, которые она содержит
Примеры
$sName = 'String data';
$oUser = new User();
$aSettings = array();
$iNum = 5;
$bErrors = false;


Если в переменной могут хранится данные нескольких типов, то ставим m (mixed)
$mData = "string";
$mData = false;
а почему смысла не имеет? Даже передовик PHPstorm далеко не всегда знает что будет в переменной
Например:
$oHelper = HelperDecorator::getHelper('HelperName');

Автокомплита для $oObject ожидать не стоит
Не знаю как PHPStorm, но если вы укажете в PHPDoc тип возвращаемого значения для getHelper, то автокомплит в Eclipse PDT у вас будет.
Да. А если вдруг тип возвращаемого значения динамический, то можно непосредственно в перед вызовом написать докблок var ClassName
Потому, что потом вы решите поменять тип, и дальше сами понимаете.
Тут как с передачей интерфейсов вместо классов.
Мартин Фаулер, Рефакторинг, замена массива объектом.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории