I want (at this moment tyring) to follow the SOLID principles, but my mind is going to blows up.
I read a lot of posts about Repository Pattern in Laravel to follow the SOLID principles. My question is very similar to this question. But I don't understand how can I don't violate the Open/Closed Principal in the Factory Pattern
I'm developing a Two Factor Authentication system and I have multiple method to use as tfa.
Right now:
Let's jump to the code:
Controller: (Without factory)
public function index(Request $request)
{
// Violate the OCP. I'm modyfing the class.
switch ($request->method) {
case 'authenticator':
$tfaMethod = new Authenticator;
break;
case 'sms':
$tfaMethod = new SMS;
break;
}
return (new TwoFactorMethod)->process($this->currentUser, $tfaMethod);
}
TwoFactorMethod class:
public function process($user, MethodInterface $method)
{
return $method->process($user);
}
Each method have their own class. It's ok. But if I want to add a new method, such as: E-mail i'll broken the OCP in the class using the switch case.
How can I "fix"? Or is just a misunderstanding from my side?
Thank you!
You could use a TfaMethodRegisty
, maybe something like this:
class TfaMethodRegistry
{
protected $methods = [];
public function register($name, $class)
{
$this->methods[$name] = $class;
}
public function get($name)
{
return $this->methods[$name];
}
}
Then you populate it for instance in your 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;
});
}
And then you can just let the Laravel IoC-Container inject into your controller or wherever you need it:
public function index(Request $request, TfaMethodRegistry $registry)
{
$tfaMethod = $registry->get($request->method);
return (new TwoFactorMethod)->process($this->currentUser, $tfaMethod);
}
So basically you're treating the available methods as configuration but can also add more at runtime without editing anything.
Just a little tip: Don't go too crazy with this and don't take the whole SOLID-thing too religiously. More often than not, KISS is way better than SOLID :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With