将以下代码作为我想要的示例:
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:
// ----------------------
}
}
我想实现一种工厂类。
假设我想拥有一个MySQLSomethingRepository,其中包含来自MySQL的数据...注入我的SomethingController ...某处我需要声明
SomethingController( new MySQLSomethingRepository() )...
希望我的工厂班级能够处理......
我正在做的当前方式是强制与数据源直接耦合......这使得用以下方法进行测试的情况非常困难:
private $somethingRepository = new MySQLSomethingRepository();
所以想象一下,如果我在其他控制器的负载中使用了相同的存储库,并且我想将我的数据库源更改为某些json数据,并且我实现了以下存储库“JsonSomethingRepository”,我必须将所有控制器更改为:
private $somethingRepository = new JsonSomethingRepository();
我如何实现我的Factory类,以便它可以处理在AddBindings函数中创建我的控制器类要求的实例?
答案 0 :(得分:0)
在Adapter模型中设计一个抽象类,并为子类提供一些常用方法。 您可以使用适配器设计两个repos,以便在控制器中注入。
我的建议是使用Abstract类并按以下方式执行:
class SomethingController extends AbstractController {
}
abstract class AbstractController {
protected $somethingRepository;
public function __Construct(ISomethingRepository $repo) {
$this->somethingRepository = $repo;
$this->AddBinding ( ISomethingRepository, MySQLSomethingRepository );
}
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)
}
}
希望这会有所帮助。