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