All streams
Search
Write a publication
Pull to refresh
4
0
Александр @BoShurik

Symfony-разрботчик

Send message

Судя по источнику перевода, это у автора стиль такой, а не у переводчика

Помельче: хелперы для работы с конфигами, или какими-то данными.

Что вы под этим имеете в виду?

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

https://github.com/symfony/website-skeleton/blob/4.0/composer.json


 "require": {
        // ...
        "symfony/webpack-encore-pack": "*",
        // ...
    },
    "require-dev": {
        // ...
        "symfony/maker-bundle": "^1.0",
        // ...
    },
В Симфони есть генератор готовых интерфейсов?

https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html


Встроенный удобный сборщик фронтенда как у Ларавел?

https://symfony.com/doc/current/frontend.html

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

А в чем именно оверинженеринг? Простенькая фэктори + строчка в конфиге


Symfony\Component\Security\Core\User\UserInterface:
    factory: ['@App\UserProvider', 'get']

<?= — это не short-tag, а алиас на <?php echo, <? — вот short-tag
http://php.net/manual/ru/language.basic-syntax.phptags.php


Тег <?= доступен всегда, вне зависимости от настройки short_open_tag.

Не рассматриваете вариант выпустить хотфикс, где отключите эту возможность? Все-таки минорный релиз не должен ломать BC

Попытался поставить, но не заработало. Полагаю, потому что APIURL захардкожен (http://grigorov.com/abi/index.php)

У меня в свое время получилось что-то вроде этого: https://github.com/BoShurik/telegram-bot-example. Отличие в том что я запоминаю не только команду, но и данные которые ввел пользователь, т.о. можно, например, заполнить заявку пошагово

Не скажу за автора, но я отказался из-за странной системы команд: невозможно пробросить свои зависимости в конструктор, как следствие — сложно интегрировать с существующим сайтом/приложением. Это больше похоже на фреймворк для создания бота, чем на библиотеку :)

При вашем подходе все равно придется следить за обновлением безопасности и фиксами ошибок (никто ведь не может быть уверен, что вы выкинули именно ту часть, которая эти ошибки содержит)


Ну и при подходе с композером никто не заставляет ждать цепочку "issue — fix — tag", всегда можете форкнуть и использовать форк до исправления ошибки.

Зачем хранить пароли в одном файле/файлах, а не в конкретных переменных окружения?
Хотя бы поэтому: https://twitter.com/o_cee/status/892306836199800836

Всё, что вы должны знать о переменных окружения в PHP:
Тенденция иметь только одну переменную, как APP_CONFIG_PATH, и читать её через '%env(json:file:APP_CONFIG_PATH)%' для меня выглядит как заново изобретать старый добрый parameters.yml

Увы но так нельзя. Точнее в этом мало смысла, т.к. у нас будет доступ ко всему конфигу сразу, а не к конкретному ключу
https://github.com/symfony/symfony/issues/24674#issuecomment-340267955

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

LuaJit на 7 месте с 8 секундами

AwesomeAbility в моем примере далека до God-object, хотя она и правда имеет многовато обязаностей. Но слишком много обязаностей не всегда означатает God-object.

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


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

DI контейнер. Если говорить о PHP и Symfony в частности, то даже конфигурировать почти не придется. Думаю в других языках есть аналоги.


Стейт и отображение решил бы так:


Код
class Unit
{
    private $abilites;

    public function activateStimPack(EventDispatcher $dispatcher)
    {
        $ability = new StimPackAbility($this, 10 /* seconds */);
        $dispatcher->dispatch(Abilities::STIM_PACK_ACTIVATE, $ability);
    }

    public function deactivateStimPacks(EventDispatcher $dispatcher)
    {
        $abilities = $this->getAbilities();
        foreach ($abilities as $ability) {
            $dispatcher->dispatch(Abilities::STIM_PACK_DEACTIVATE, $ability);
        }
    }
}

class StimPackListener
{
    public function __construct(EventDispatcher $dispatcher, GameTimer $timer)
    {

    }

    public function onActivate(StimPackAbility $ability)
    {
        $ability->getUnit()->addAbility($ability);
        // Add other effects
        $timer = $this->timer->tick(function() use ($ability){
            $ability->decSeconds();

            if ($ability->getSeconds() == 0) {
                $this->dispatcher->dispatch(Abilities::STIM_PACK_DEACTIVATE, $ability);
            }
        });

        $ability->setTimer($timer);
    }

    public function onDeactivate(StimPackAbility $ability)
    {
        $ability->getUnit()->removeAbility($ability);
        // Remove other effects
        $ability->getTimer()->destroy();
    }
}

У вас вместо одной супер-абилити будет множество эвентов, которые просто влияют на юнит

В моем подходе эвент = абилке. Я ее рассматриваю не как объект, а как процесс. В текущем варианте вполне можно их сохранять и выводить.


Кто отвечает за применение эффектов в вашем подходе? Сама абилка или юнит к которому она добавлена?
И как активируются AwesomeAbility из вашего предыдущего примера? Ведь по условию ее эффекты распространяются не только на того, кто ее использовал


На самом деле не претендую на правильность моего подхода. Просто решил посмотреть как он ляжет на вашу задачу. И вроде пока узких мест не вижу.

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

$this->getEventDispatcher()->dispatch(Ability::AWESOME, new AwesomeAbilityEvent($subject, $target));

Вместо того, чтобы создать одну AwesomeAbility — создать 5 подабилок? А что это даст?

Это не пять абилок, это пять обработчиков одной абилки. Таким образом решаем проблему Single Responsibility. В вашем варианте у вас получается God-object

Я бы через Event Dispatcher сделал:


Как-то так
<?php

abstract class AbstractAwesomeAbilityListener
{
    public function __construct(
        GameTime $time, 
        PlayerStorage $storage, 
        GameConfig $config
    )
    {
        // ...
    }

    abstract protected function doActivate();

    public function onActivate()
    {
        if (!$this->isAllowed()) {
            return;
        }

        $this->doActivate();
    }

    /**
     * @return bool
     */
    protected function isAllowed()
    {
        // ...
    }
}

class CrewListener extends AbstractAwesomeAbilityListener
{
    public function __construct(
        CrewContainer $container, 
        GameTime $time, 
        PlayerStorage $storage, 
        GameConfig $config
    )
    {
        parent::__construct($time, $storage, $config);

        // ...
    }

    protected function doActivate()
    {
        // ...
    }
}

class PlantsListener extends AbstractAwesomeAbilityListener
{
    public function __construct(
        CrewContainer $container, 
        GameTime $time, 
        PlayerStorage $storage, 
        GameConfig $config
    )
    {
        parent::__construct($time, $storage, $config);

        // ...
    }

    protected function doActivate()
    {
        // ...
    }
}

class EnemyListener extends AbstractAwesomeAbilityListener
{
    public function __construct(
        CrewContainer $container, 
        GameTime $time, 
        PlayerStorage $storage, 
        GameConfig $config
    )
    {
        parent::__construct($time, $storage, $config);

        // ...
    }

    protected function doActivate()
    {
        // ...
    }
}

И тут мы пришли к тому, что вам писал mayorovp. На один слой больше за счет такой вот обертки.
Либо имеем нарушение принципа единственной ответственности, когда вебсокет сервер у нас еще занимается парсингом вывода и перезапуском упавших процессов.

Information

Rating
Does not participate
Location
Владимир, Владимирская обл., Россия
Date of birth
Registered
Activity