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 опередил меня с отличным ответом :) обратите внимание, что, помимо того, что делает вещи (вероятно, излишне) более абстрактными, это решение также имеет большой недостаток в том, как знания были перемещены из домена на уровень инфраструктуры фреймворка. Это привяжет тебя к рамкам, что вы вообще хотите избежать.
