Pull to refresh
35
0
Струков Дмитрий @mitaichik

Пользователь

Send message
Хорошая работа, но, имхо, любой подобный пост будет слишком поверхостным. Именно поэтому в «Совершенном коде» около 900 страниц.

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

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

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

В целом же, имхо, когда у разработчика довольно большой опыт, то после прочтения задачи архитектура рисуется за пару минут. И делать по правильному ничуть не дольше чем быдлокодить, как правило. Даже более того — опытный разработчик не будет быдлокодить в принципе, ибо в таком случае он не получит удовольствие от работы.
В посте не предлагается использовать их для валидации пользовательских данных — наоборот — есть пример где показано объяснено почему в этом случае не стоит бросать эксепшн.
<чуть чуть сарказма>Автор, в 4 абзаце речь идет о стандартах и лучших практиках, как насчет PSR1,2? :)</чуть чуть сарказма>


Согласен. Просто я работаю в проекте который начали писать задолго до PSR. И переводить CodeStyle на PSR желаение нет: попробуйте смержить 2 больших файла, когда один разработчик переделал CodeStyle, а другой закоммитил +500 изменений — это может правреатиться в ад. Поэтому и не трогаем CodeStyle..., на качество кода как крути не влияет.
код, утыканный «throw new Exception» — это, как минимум, странно.

Просто в контексте тех мест класс эксепшна не так важен как именно его наличие, поэтому я упростил код. Это ж пример, не более.
Про обработку исключений мало сказано

Это все к мануалу, статья не про это, а про то что, как верно подметил FanatPhp — обработка исключений не заключается чисто на try catch
среди примеров презираемый многими «catch (Exception)

В статье только один пример с catch (Exception) и он вовсе не про обработку исключений, а про откат изменений. Поэтому там все верно — именно catch (Exception) там и должен быть.
Да, однозначно в отдельных файлах.

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

Про папочки — это как душе угодно. Я обычно делаю папку exceptions в папке модуля/компонента и туда складываю все классы эксепшенов.
Таким образом получается вот так (неймспейсы повторяют физическое размещение):

kladr\KladrService
kladr\exceptions\AddressNotFoundException
kladr\exceptions\UnresoledAddressException
Это же все в манулае можно прочитать. Я же хотел сосредоточиться на немого другом аспекте: как верно подметил FanatPHP — что обработка исключений не заканчивается на try catch
Совершенно верное замечание ) С вашего позволения, добавлю это в пост.
Точнее sudo apt-get install gearman-tools mod-gearman-tools
В жизни не поверю, что яндекс хранит пароли в открытом виде. Не может такого быть.
public function setStatus(int $status)

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

   public function actions()
    {
        return [

            'view1' => [
                'class' => ARViewAction::class,
                'modelClass' => User::class,
                'criteria' => [
                    'with' => [
                        'orders' => [
                            'condition' => 'sum < 1000'
                        ]
                    ]
                ]
            ]
        ];
    }


Вот пример когда вьюха подразумевает что ей передают дата-провайдер:

   public function actions()
    {
        return [

            // Если вьюха подразумевает что ей передают dataProvader'ы
            // в AR метода getRelationCriteria(relationName, additionalCriteria) нет, но его можно самому дописать
            'view2' => [
                'class' => ARViewAction::class,
                'modelClass' => User::class,
                'dataProviders' => function(User $user){
                        return [
                            'ordersDataProvider' => [
                                'modelClass' => Order::class,
                                'criteria' => $user->getRelationCriteria('orders', 'sum < 1000')
                            ]
                        ];
                    }
            ],
        ];
    }
Это не так, ибо полностью зависит от реализации $client->orders. Например, если он реализован с помощью релейшена AR — выборка будет единоразовой. В трейте для релейшенов yiimongodbsuite, который я написал, данные так же кешируется.

Если ArrayAccess написан так, что при каждой итерации будет производиться запрос — вы правы. В любом случае, это полностью лежит совести разработчика.
Возможно, я не достиг уровня «будды» в программировании, но, если честно, я не понимаю повсеместного использования геттеров-сеттеров. Как бы да, в некоторых местах это необходимо. Например, критерия может быть в двух видах: CDbCriteria и array. В таком случае логично переписать сеттер который приводил бы тип к нужному. Но абсолютно везде — имхо, это лишний код и тупо усложняет.

Что касается приведенного кода, то, во-первых, код чисто для примера, и многое там опущено дабы не усложнять. Во-вторых, там мы не присваиваем никаких безопасных свойств: все присвоения атрибутов модели идут через setAttributes, который в свою очередь смотрит на валидаторы, и при сохранении проверяет валидность. Другие присвоения (например, присвоение критерии EMongoDocumentDataProvider) реализованный внутри соответствующего расширения и нам не надо заботиться об этом. Присвоения свойств экшена — это уже чисто на нашей совести. Но Yii нам помогает: если мы присвоим несуществующую вьюху или скоуп — он нам однозначно даст нам об этом знать.

Насчет «багов Yii» и «поломает бизнес логику и данные»: Что касается багов Yii, то я доверяю разработчика Yii, и баг Yii — это в какой-то степени форс-мажор. Но, естественно на «безбаговость» не приходиться рассчитывать — сломаться может не только Yii, а любой экстеншн, или даже собственный код. Для этого у нас есть пост-валидация бизнес-операций. И в случае ошибки — откатывать всю бизнес-операцию, с помощью транзакций или как-то по другому. В этом посте я не описал эту тему, ибо он и так слишком большой, плюс тема бизнес-операций — это тема «М». Это все я опишу в следующем посте.

Information

Rating
Does not participate
Location
Россия
Date of birth
Registered
Activity