Comments 66
Статику надо уметь готовить ))
А приведите примеры. Причем лично меня интересуют именно те примеры, которые обладают состоянием.
Ну ОК, состав первичного ключа (список полей, входящих в него) — это свойство* класса моделей, а не конкретной модели. Не нужно, как в Ларавеле, создавать объект-модель, чтобы просто узнать, какой у нее ПК.
* «свойство» здесь вполне может быть публичным методом, возвращающим разный результат в зависимости от get_called_class(), например
Правильно я понимаю, что для получения состава PK необходимо сделать запрос в базу и получить информацию по определенной таблице (которая, возможно, лежит в каком-то методе или свойстве — их тоже статиком делать из-за вашего сценария)? И подобный запрос (с кешированием) делается в ларавеле при создании модели? Тогда почему не воспользоваться этим (что и делает ларавел)?
А что если модель может получать данные из нескольких разных таблиц, в которых разные PK. Какая именно таблица выбирается по внешним факторам. В этом случае проще и правильнее именно создавать объект модели, а не эмулировать такое поведение.
Если я прав — статический метод не нужен, скорее вреден.
Тут, скорее всего, о получении состава ключа из данных маппинга ActiveRecord, который в некоторых реализациях "зашивается" в данные уровня объектов, в некоторых в данные класса, а в некоторых вообще базируется на соглашениях типа "имя класса равно имени таблицы".
Просто я хочу знать, какое поле (поля) образуют первичный ключ. Это может быть константа, может быть какая-то функция, которая этот состав мне сообщит.
Неважно.
Важно то, что состав первичного ключа — свойство не объекта, но класса. Если допустить обратное, получается абсурд — каждая запись может иметь разные по составу первичные ключи?
Просто я хочу знать, какое поле (поля) образуют первичный ключ. Это может быть константа, может быть какая-то функция, которая этот состав мне сообщит.
Ну тогда проще и правильнее константу, не? Ну а если вам нужен именно какой-то метод — правильнее вынести его в хелпер и вызывать с передачей в него параметров, от которых зависит результат. Собственно, я про такое использование и говорил выше ;)
Важно то, что состав первичного ключа — свойство не объекта, но класса.
На самом деле — нет. По вашему примеру — состав ключа вообще не относится к моделям.
Это свойство не столько класса, сколько метаданных объекта. Их можно получать из объекта, из класса, откуда-то ещё.
это свойство* класса моделей, а не конкретной модели.
а я называю это метаданными. И предпочитаю что бы метаданные модели жили отдельно от самой модели. Более того, я предпочитаю иметь объект, описывающий метаданные и другой объект мне их предоставляющий.
Сравнение на свехмалых числах не только не даёт полной картины, но и при следующем запуске результат может оказаться противоположным
Конкретно по вашему кейсу gogle for: "Lazy Load", "DI containers".
А вообще судить по набору говнокода о чём бы то ни было — мягко говоря странно.
Обычный объект в js занимает 40–80 байт.
Читаем в коде:
echo A::someStatic()->prop;
и тут же, ниже:
не обязательно создавать объекты в ООП, и можно обходиться без них экономя память
Вы серьезно верите в то, что в вашем примере объект не создается?
Я вас огорчу, пожалуй. Создается, занимает память, требует лишнего времени на возврат из локального контекста метода в вышележащий контекст (в отличие от конструктора) и будет в память торчать, пока не придет к вам GC.
То, что вы суслика не видите — не значит, что его нет!
P.S. Статья, конечно же, не уровня хабра…
Активное использование статических методов класса мало чем отличается от использования обычных функций, оперирующих глобальными переменными, со всеми вытекающими. Разве что чуть лучше инкапсуляция и автозагрузка прикручивается в PHP.
Не надо считать, что мол «статический метод — всегда зло». Вы же в курсе, что в PHP нет по-настоящему динамических методов, они все по факту статические?
не забывайте еще про пространства имён.
а у функций с этим какие-то проблемы?
«статический метод — всегда зло»
никто никогда такого и не говорил. Разве что те, кто не понимают разницу между статическими методами и глобальным стэйтом. Если статика не имеет сайд эффектов — то все хорошо.
Да, у них есть применение в текущей ситуации, но в большинстве случаев оно приносит больше проблем чем решает.
Или вернуть, присвоить переменой и т. п.
$className = getSomeClassName();
$className::someMethod;
// или
getSomeClassName()::someMethod();
Да, не сами классы не сущности первого класса. Но это легко обходится с помощью использования в качестве сущности имени класса.
Но это легко обходится с помощью использования в качестве сущности имени класса.
Завязка на имя класса это в целом очень и очень жесткое ограничение. Вы не находите?
Поясните свою философию, будьте добры. Ибо мне, например, непонятно и я могу сделать неправильные выводы из фразы "таков уж PHP". Например "и так сойдет".
Как бы он ни был плох, он занимает около 90% мирового рынка веб-разработки и немалую долю в других нишах.
Можно бесконечно хейтить. А можно изучить и пользоваться.
Я за второй вариант.
А вы?
и немалую долю в других нишахЭто в какой нише, кроме веба, PHP имеет немалую долю?
В основном это различная потоковая обработка данных, нормализация, загрузка из в БД, агрегация в БД и построение различных отчетных данных.
Сплошной cli.
Мм… а что тогда web php? Просто то что вы перечислили — это обычное дело в контексте web разработки.
следуя этой логике любой проект под мобилки это не web (что в целом правильно).
Или же, если у меня есть морда, которая представляет из себя простенький дашборд, а под копотом десяток демонов которые занимаются обработкой данных — это уже не web или уже web?
Я больше о том что делить web и не web если по итогу делается одно и то же (работа с базой данных, обработка данных)?
Вот если бы вы сказали что под десктопы на php пишите — тут да, "другие ниши".
"web php" принимает на вход прежде всего всякие $_GET, $_POST и т. п.
не "web php"их игнорит
:)
Почему PHP выбран для cli? Основная причина, когда могут на этот вопрос ответить что-то кроме "а больше я ничего не знаю на достаточном уровне", это "на 90% кодовая база пересекается".
Естественно, если сравнивать более или менее одинаково (по качеству) написанный код.
Например, вот в этой инфографике в самом конце есть пример по скорости построения фрактала Мандельброта.
вот только в подавляющем большинстве случаев вам CLI приложение не фракталы Мандельброта строят, а с IO взаимодействуют, и тут php начинает сильно проигрывать тем же python/ruby в плане экосистемы.
У меня как-то был CLI скриптик на php который kmeans класстеризацией занимался, и да, на 7.0 оно делало 400KK итераций примерно за 3 минуты. Но я бы не совсетовал другим так делать.
p.s. в последних версиях cruby появился jit. Для python и что бы строить фракталы есть pypy. Ну это что бы было чуть более честно.
Я за второй вариант.
А вы?
Я за разумное использование доступных фич. То есть если что-то можно сделать в языке, это далеко не означает что эту комбинацию фич стоит использовать в новом коде.
Напомню, что вопрос мой был относительно описанных вами примеров, завязке на имена классов и в целом повсеместное использование статики.
он занимает около 90% мирового рынка веб-разработки
80% из которой можно вообще в расчет не брать.
У PHP есть такие возможности, относящиеся скорее к "хакам", чем к "лучшим практикам", но из этого не следует, что нужно на них строить архитектуру приложения в целом.
Будьте добры поясните, что вы считаете хаком, недопустимым к использованию в архитектуре?
Спасибо
Построение архитектуры на основе "хаков", использующих динамическое задание имени класса в строковых переменных, сильно усложняет сопровождение и развитие системы с такой архитектурой. Как минимум, за счёт наличия множества зависимостей, которые гораздо сложнее обнаружить при анализе.
Как локальное решение, например, в DI-контейнере, выдающим по SomeInterface::class инстанс реализации — вполне. Как основной способ передачи ссылок на данные — очень усложняет понимание.
Опишите мне интерфейс для функции через phpdoc. А потом попробуйте описать дженерики для коллекций/промисов/etc. Спойлер — у вас не получится.
Какой тег PhpDoc документирует переменную, параметр или результат как содержащую имя класса?
Какой тег PhpDoc проводит проверку в рантаймк параметра или результата на содержание имени класса, унаследованного от базового?
не смотря на то что я с вами согласен, относительно
Какой тег PhpDoc проводит проверку в рантаймк параметра
AOP + Design By Contract покрывает все эти вещи и даже больше.
Не спорю, но это требует как наличие "продвинутой" культуры разработки, так и "продвинутого" инструментария, по сравнению с "мэйнстримовыми" "лучшими практиками". Читай: "это более дорого в текущих реалиях рынка".
В какой-то мере ровно наоборот. Те же роуты в виде аннотаций в классах контроллера относятся скорее к AOP, чем к классическим парадигмам.
ты про прокси классы?
Налицо явное непонимание идеи ООП.
но это тот самый оверхэд от которого можно отказаться.
если вас парит факт оверхэда на создание объектов — почему бы не отказаться от пересоздания объектов на каждый запрос? Вот это было бы разумно и реально давало бы профит. А так — это просто стыд.
не обязательно создавать объекты в ООП
вот только это не ООП а структурное программирование в лучшем случае. Идея ООП в том, что у вас не просто есть объекты, а в том что они взаимодействуют между собой, что есть late binding. Что до оверхэда — если данные не будут покидать приделов объектов, и если вы выкидываете из уравнения модель выполнения "обработай и умри" — то оверхэд будет как раз таки не в вашей реализации.
то есть банальный пример. Продемонстрируйте мне как будет выглядеть late biding в контексте статических методов? Скажем, такой простой шаблон как декоратор реализуйте.
Мне, как и многим моим коллегам, приходилось сталкиваться с ситуацией, когда расширение и поддержка существующего кода — чистый ад, а возможности все это отрефакторить к такой-то матери — нет, гонят новыми фичами. И что обидно — джуники и матерые рукожопы здесь на коне, потому что за 5 минут могут навалять косо-криво работающее решение, а шишки будешь получать ты, опытный разработчик, потому что уже полдня возишься и не можешь исправить эту «маленькую» но неприятную ошибку, исправление которой поднимает на поверхность все новые и новые косяки давно отошедших от проекта коллег…
В таком случае я рекомендую заняться рефакторингом втихую, чуть понизив свою производительность, при этом чуть пожертвовав своей свободой. понемногу, не спеша, умело расставляя такие «костыли», которые в нужный момент превратятся в более соответствующую архитектуру. Вряд ли внутренний перфекционист будет доволен поностью, но самые вопиющие недостатки, влияющие на ясность кода и производительность, будут сглажены.
Поверьте, таким образом уже был «спасен» не один проект.
Код друзей таких авторов
BaseClass, ClassA : BaseClass, ClassB : BaseClass, ...
ClassA a;
ClassB b;
ClassC c;
if(a != null)
{
a->someMethod();
} // Даже без else, хотя инициализируется только одна переменная и группы
if(b != null)
{
b-> someMethod();
}
Тоже не понимают что такое ООП, потому как делали только простые программки с парой функций, а что такое сложная система даже не представляют.
PS. Это, конечно, не без создания объектов, но проблемы там примерно те же.
создавался объект mysqli и присваивался свойству sql каждого объекта. Можно только представить сколько лишних действий в пустую и какой перерасход оперативной памяти происходит.
Да, ссылки нынче дорогие(((
Наверно сравнение на «сверхмалых» числах не дает полной картины
И смысла не имеет, если на то пошло
но это тот самый оверхэд от которого можно отказаться.
Это экономия на спичках
Причина не любви к работе с объектом (при передаче другому методу), в том что у меня есть фобия что он не тот за кого себя выдает
Type hinting появился еще в 5.1
чтобы не было непредвиденных результатов лучше проверить его содержимое, что может оказаться муторной работой
Как же инкапсуляция?
Я не спорю, бывают ситуации, когда статика оправдана, например методы стандартной библиотеки, и то далеко не всегда. Но память — это вообще не тот случай. То, что парни из вашей работы не смогли в lazy load — это печально.
Но, в большинстве случаев статика приводит к:
- Бесконтрольной связности и хрупкости проекта
Если вы меняете статический метод — вы меняете его для всей системы сразу, этого нельзя сделать конкретно для этого сервиса и для следующего, на переписав их за компанию.
- Экспоненциальному росту сложности тестирования
Ваши тесты будут на прямую зависеть от реализации статических методов и вы их не сможете подменить.
- Статика с состоянием — это пичалька
Вы просто должны верить, что она как-то работает и ниоткуда она не будет вызвана не правильно, или не в той последовательности.
ООП без «О»