Laravel SOLID с использованием шаблона репозитория

Я хочу (в данный момент tyring) следовать твердым принципам, но мой ум собирается взорваться.

Я прочитал много сообщений о Шаблон Репозитория в Laravel следовать твердым принципам. Мой вопрос очень похож на этот вопрос. Но я не понимаю, как я могу не нарушать Открыть/Закрыть Принципал на Шаблон Фабрики

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

сейчас:

  • Приложения
  • SMS

давайте перейдем к коду:

2 ответов


вы могли бы использовать TfaMethodRegisty, может, что-то вроде этого:

class TfaMethodRegistry
{
    protected $methods = [];


    public function register($name, $class)
    {
        $this->methods[$name] = $class;
    }


    public function get($name)
    {
        return $this->methods[$name];
    }
}

затем вы заполняете его, например, в своем AppServiceProvider:

public function register()
{
    $this->app->bind('App\TfaMethodRegistry', function ($app) {
        $registry new TfaMethodRegistry;

        $registry->register('sms', new Sms);
        $registry->register('authenticator', new Authenticator);

        return $registry;
    });
}

и после этого вы можете как раз позволить Иок-контейнеру Ларавел впрыснуть в ваш регулятор или везде, где вам нужно оно:

public function index(Request $request, TfaMethodRegistry $registry)
{   
    $tfaMethod = $registry->get($request->method);

    return (new TwoFactorMethod)->process($this->currentUser, $tfaMethod);
}

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

просто небольшой совет: не сходите с ума с и не принимайте все это слишком религиозно. Чаще всего,поцелуй лучше, чем SOLID:)


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

пример того, как это может смотри:

class TwoFactorAuthenticatorFactory {
    public static function createFromMethod(string $method): TwoFactorAuthenticator
    {
        switch ($method) {
            case 'authenticator':
                return new Authenticator();
            case 'sms':
                return new SMS();
        }

        throw new RuntimeException(sprintf('Method %s could not be resolved to an authenticator.', $method));
    }
}

использование:

TwoFactorAuthenticatorFactory::createFromMethod($request->method);

Я планировал дать вам краткое изложение того, как вы решите это "догматически", но @Quasdunk опередил меня с отличным ответом :) обратите внимание, что, помимо того, что делает вещи (вероятно, излишне) более абстрактными, это решение также имеет большой недостаток в том, как знания были перемещены из домена на уровень инфраструктуры фреймворка. Это привяжет тебя к рамкам, что вы вообще хотите избежать.