Проблема именование классов

Yoskaldyr

"Спамер"
Партнер клуба
Я в курсе что название темы звучит немного по дибильному.
И я в курсе что именование переменных и функций одна из главных проблем программирования, но все же...


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

Поэтому вопрос и возник, т.к. сейчас сторм по умолчанию хочет вынести в use все имя класса полностью, т.е. чтобы использовать в коде самую последнюю часть, чем большинство разработчиков активно пользуются.
Как результат очень часто в коде могут возникать дубликаты имен классов, особенно при использовании сторонних библиотек.
Также при чтении кода некоторых либ приходится тратить в разы больше времени, чтобы определить а что это за User - дто, сервис или еще что.
А т.к. не всегда есть возможность сменить структуру готового проекта, то можем получить кучу User, Model, Adapter и т.д. от разных вендоров.

Да в курсе что можно обращение к классу и по полному имени и по частичному use и по алиасу.
Но вот по полному имени иногда такие уровни вложенности и такие названия у сторонней либы, что вызов конструктора с парой параметров может быть полным нечитаемым трешем на вид.
По частичному пути, тоже вопрос - какую часть выбрать, чтобы код читался легко.

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

И как защитить свой код от засирания неймспейсами сторонних библиотек (речь не идет о том когда разовое использование, а когда надо использовать часто и в разных местах)? Писать свои обертки или еще как?

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

P.S. Вообще как-то сумбурно получилось, щас у меня нереальная жара и кондера вообще нет, а поставить нельзя :(
 
Последнее редактирование:

nllabs

Новичок
И как защитить свой код от засирания неймспейсами сторонних библиотек (речь не идет о том когда разовое использование, а когда надо использовать часто и в разных местах)? Писать свои обертки или еще как?
Вот в чем вопрос - использовать use или не использовать use :)

Используйте use. Или Вы считаете, что без use будет удобнее ?
Я, честно говоря, не вижу проблемы.
Может быть речь идет об этом: ?

use My\Full\Classname as Another;
 

fixxxer

К.О.
Партнер клуба
Если по имени класса без неймспейса в контексте и так понятно - то use.
Если непонятно - то подумать, как переименовать класс, чтобы было понятно. Если же это сторонняя штука - use с алиасом.
 

Yoskaldyr

"Спамер"
Партнер клуба
да понятно что use с алиасом, но просто напрягает. Особенно когда во многих местах надо.
Учитывая что сторм так и норовит при первом использовании вынести в use полное имя класса, можно автоматом сделать.

тупо для примера:
PHP:
use BitWasp\Bitcoin as BTC;
.....
        $network = BTC\Network\NetworkFactory::bitcoin();

        $adapter = BTC\Bitcoin::getEcAdapter();
        $slip132 = new BTC\Key\Deterministic\Slip132\Slip132(new BTC\Key\KeyToScript\KeyToScriptHelper($adapter));
        $bitcoinRegistry = new BTC\Network\Slip132\BitcoinRegistry();

        $config = new BTC\Key\Deterministic\HdPrefix\GlobalPrefixConfig([
            new BTC\Key\Deterministic\HdPrefix\NetworkConfig($network, [
                $slip132->p2pkh($bitcoinRegistry),
                $slip132->p2shP2wpkh($bitcoinRegistry),
                $slip132->p2wpkh($bitcoinRegistry),
            ])
        ]);

        $serializer = new BTC\Serializer\Key\HierarchicalKey\Base58ExtendedKeySerializer(
            new BTC\Serializer\Key\HierarchicalKey\ExtendedKeySerializer($adapter, $config)
        );
вот такие конструкторы напрягают!

Но если делать по умолчанию как предлагает сторм то будет нечитаемое нечто.... Да код короче, но что делает - вообще хз, учитывая что в приложении и своих Registry, Helper, Config, Adapter классов предостаточно.
PHP:
// здесь куча use
//...
        $network = NetworkFactory::bitcoin();

        $adapter = Bitcoin::getEcAdapter();
        $slip132 = new Slip132(new KeyToScriptHelper($adapter));
        $bitcoinRegistry = new BitcoinRegistry();

        $config = new GlobalPrefixConfig([
            new NetworkConfig($network, [
                $slip132->p2pkh($bitcoinRegistry),
                $slip132->p2shP2wpkh($bitcoinRegistry),
                $slip132->p2wpkh($bitcoinRegistry),
            ])
        ]);

        $serializer = new Base58ExtendedKeySerializer(
            new ExtendedKeySerializer($adapter, $config)
        );
 

fixxxer

К.О.
Партнер клуба
да понятно что use с алиасом, но просто напрягает
Меня не напрягает. Alt+Enter - Alias - парам - enter, че сложного то?

Да и не так часто надо, со сторонними либами в основном. Если ты сам себе понаделал всяких \Foo\Registry, \Bar\Registry и \Baz\Registry, то проблема в тебе.
 

fixxxer

К.О.
Партнер клуба
А, еще иногда делаю вот так:

PHP:
use Some\Library;

$foo = new Library\Foo();
$bar = new Library\Bar();
Но это требует ручных телодвижений, потому только когда очень надо.
 

Yoskaldyr

"Спамер"
Партнер клуба
Так не я себе надумал :)))) Не всегда работаешь с кодом который сам написал....
 

AnrDaemon

Продвинутый новичок
Если непонятно - то подумать, как переименовать класс, чтобы было понятно
И писать классы типа Exception\NotFoundException ?
Простите, но я считаю, что IDE должно помогать писать код, а не быть необходимым условием для написания кода, или требовать определённой структуры кода для работы себя, любимой.
 

fixxxer

К.О.
Партнер клуба
NotFoundException не надо.

UserNotFound, FileNotFound, HttpNotFound и т.д. То, что exception, и так понятно: что еще может быть в throw или catch?

IDE, конечно, поможет разобраться, даже если у тебя 100 классов вида User\Model, Post\Model, Comment\Model etc - но это не означает, что так стоит делать.
Что касается необходимого условия - не, ну как, можешь писать хоть в ed, но если у тебя проблемы с тем, чтобы автоматически переставить местами два аргумента в функции при рефакторинге, то нафиг ты такой красивый.
 
Последнее редактирование:

Yoskaldyr

"Спамер"
Партнер клуба
User\Model, Post\Model, Comment\Model
такое как раз редко бывает, т.к. обычно группируют по типу класса, типа все вьюхи в одной папке, все ентити в другой. и это обычно диктует само приложение/фреймворк. поэтому получаем куча User или продобных (Model\User, View\User).
Т.е. в данном случае если вынести в use корень вьюх или моделей, то автокомплит нормально будет работать для Model\User, View\User, но это надо в иде делать руками и оооочень не удобно. А прописывать каждый раз алиас в use в виде ModelUser и ViewUser - это вообще бред.

Вот со сторонними либами как раз что-то подобное User\Model, Post\Model, Comment\Model, только обычно это какой-то Config, Adapter, Proxy и т.д., моделей пока в сторонних либах не встречал :)


Вот потому и спросил какие есть практики именования/группировки классов для своего приложения чтобы и код короче был и оставался читабельным.
А то реально часто встречается как раз типа Exception\NotFoundException или View\UserView и т.д. И это самые короткие примеры, а часто имя класса (последняя часть) состоит на 90% из полного пути этого класса, пример в коде выше: Key\KeyToScript\KeyToScriptHelper
И это не самая жесть что встречается.
 

fixxxer

К.О.
Партнер клуба
Практика простая: имя класса всегда содержит имя существительное, описывающее его суть ("что это"), в именительном падеже, а к нему уже могут быть уточнения всякие. (Исключения - особый случай).
Просто User, соответственно, это модель.
Всякие там еще штуки - ну будет UserCollection, UserRepository и так далее.

KeyToScriptHelper это просто какое-то говно уже судя по имени - в хорошем дизайне Helpers и прочие Utils не вылезут. Впрочем, для инфраструктуры втащить всякое сторонее говно нормально, главное чтобы наружу не торчало.
 

Yoskaldyr

"Спамер"
Партнер клуба
ок, но классы же как-то группируют. Т.е. будет получаться что-то подобное такому:
Collection\UserCollection, Repository\UserRepository и т.д.

И это как раз то что очень часто встречается в сторонних либах, типа Blah1\Blah2\Blah3\Blah1Blah2Blah3Class
 

Yoskaldyr

"Спамер"
Партнер клуба
Есть у кого нибудь более менее нормальные примеры огранизации структуры большого приложения (может есть что-то опенсорсное на гитхабе). Где к примеру есть админка и публичная часть. Т.к. структура в 99% случаев диктует наименование, и использование классов внутри, то интересно глянуть.
 

Yoskaldyr

"Спамер"
Партнер клуба
Может есть у сторма возможность, комбинация клавиш или что-то подобное, чтобы вынести в use не весь класс а только часть? Просто искал по настройкам и не нашел.
 

fixxxer

К.О.
Партнер клуба
Группировать надо не по типу, а по контексту. Тот, который bounded context в DDD.
 

fixxxer

К.О.
Партнер клуба
Нет, у меня два класса Entity\User и Resource\User.
Entity отвечает за доменную логику, а Resource за представление.
Штуки типа Resource\User появляются, когда нет разделения на Write Models и Read Models.
Если у тебя CQRS, то в том, что Read Model и Write Model называются одинаково, нет абсолютно никакой проблемы, поскольку они никогда не появятся вместе.
 
Сверху