以下面的代码作为我想要的示例:
class SomethingController extends Factory
{
private $somethingRepository;
public function __Construct( ISomethingRepository $repo )
{
$this->somethingRepository = $repo;
}
}
class Factory
{
public function __Construct()
{
// The following call to AddBinding would push into SomethingController the new instance of the class denoted in my AddBinding second parameter.
$this->AddBinding( ISomethingRepository, MySQLSomethingRepository);
// So in this case, if the controller i'm extending has a construct parameter of ISomethingRepository, then make the parameter equal a new MySQLSomethingRepository()
// Then if I want to use JSONSomethingRepository in the future, I only have to change the one AddBinding call and the controller will still work.
}
public function AddBinding( $interface, $concrete )
{
// Somehow assign the constructor properties of the extending class as new instances of the bindings i have called upon in the construct of my factory class (see this class's construct)
// Pseudo code:
// ----------------------
$calledClass = get_called_class();
$class = new \ReflectionClass( $calledClass );
$method = $class->getMethod( "__construct" );
$params = $method->getParameters();
foreach( $params as $param )
{
if ( $param == $interface )
{
return new $concrete;
}
}
// /Pseudo code:
// ----------------------
}
}
我想实现一个工厂类。
- 该工厂类将由控制器类扩展。
- 工厂类将查看控制器类的构造参数,并根据工厂中的 AddBindings 方法创建对象的新实例。
假设我想要一个 MySQLSomethingRepository,其中包含来自 MySQL 的数据...注入到我的 SomethingController 中...我需要在某个地方声明这一点
SomethingController( new MySQLSomethingRepository() )...
希望这将由我的工厂类处理......
我目前的做法是强制与数据源直接耦合......这使得很难使用以下方法进行测试用例:
private $somethingRepository = new MySQLSomethingRepository();
所以想象一下,如果我在其他控制器的负载中使用了相同的存储库,并且我想将我的数据库源更改为一些 json 数据,并且我实现了以下存储库“JsonSomethingRepository”,我必须将所有控制器更改为:
private $somethingRepository = new JsonSomethingRepository();
我如何实现我的 Factory 类,以便它可以处理创建我的控制器类在 AddBindings 函数中所需的实例?