I am looking simple way to use class locator for php.
I have developed application that is working for different clients, clients requirements are very similar but with some small differences and exceptions. So code is near the same for all clients, but with some differences to implement that exceptions for each client.
I want to use same base code for all clients, I want to keep it simple but still allow customization for each client. It needs to be easy to maintain and I want to reduce cyclomatic complexity.
Sample, say I have a class A like this:
namespace src;
class A
{
public function f1()
{
// do something
}
public function f2()
{
// do something
}
public function F()
{
return $this->f1() + $this->f2();
}
}
Class A implements default behavior or most common used path. For some clients it works.
Other clients need special behavior in one or more of their methods, so my first approach was to use some if inside each method like this
class A
{
public function f1()
{
if (CLIENT === 'peter') {
// do something for client peter
} elseif (CLIENT === 'mary') {
// do something for client mary
} else {
// default client
}
}
}
It works, but I do not like because I have a lot of clients, and become difficult to read, test and maintain, and code for each method becomes very long.
Second approach I tried to extend main class for each client, something like
namespace src\peter;
class A extends \src\A
{
public function f1()
{
// do something for client peter
}
}
and when I need to use it:
if (CLIENT === 'peter') {
$className = src\peter\A::class;
} elseif (CLIENT === 'mary') {
$className = src\mary\A::class;
} else {
$className = src\A::class;
}
$object = new $className();
$object->f();
It works, it is better, because separates methods implementation for each client on separated class and it looks cleaner, but I still have two problems:
1 - From IDE like phpstorm I cannot navigate code clicking on method or class name, that is because class name now is variable.
2 - I still have that "if" on code.
I am looking for cleaner solution, some way to define current client as CONST in a configuration file and on code I just want to write
$a = new A();
and A, could be src\peter\A; or src\mary\A; depending how I configured it, and if class A is not defined for configured client then default class src\A; should be used.
is possible use some kind of class locator like this?
thanks!
Aucun commentaire:
Enregistrer un commentaire