Gab*_*tos 12 php design-patterns dependency-injection inversion-of-control service-locator
我已经编程了一段时间但从未对理解每个概念的含义感兴趣,我可能正在使用各种编程概念,但却不知道它.
服务定位器:对我来说,是指通过减少代码量来加快开发速度的快捷方式记录.一个问题是:可能Locator仅引用名称空间/类,或者我可以拥有变量注册表?
以下是我对它的理解:
$locator = new ServiceLocator()
$locator->set('app', new System\Application());
$locator->set('db', new System\Pdo());
// Get the objects
$locator->get('db')->connect();
$locator->get('app')->run();
Run Code Online (Sandbox Code Playgroud)
依赖注入(和依赖注入容器):在对象内注入对象,无论工厂模式如何,都可以更快地访问这些对象.和DI容器?
以下是我对它的理解:
$app = new System\Application(System\Config::load());
Run Code Online (Sandbox Code Playgroud)
控制反转:不了解这种设计模式(或者理解但不知道我做的是IoC)
然后,在理论上(最好用简单的例子),这些概念中的每一个意味着什么?我是正确的,还是有什么不对/可以改进?
谢谢!
Roo*_*ian 20
服务位置和依赖注入首先用于解耦类,以便可以轻松地测试和更改它们.
当你比较寄存器和决心的部分IoC容器与服务定位它似乎是相同的.
您可以使用IoC容器作为服务定位器,这被认为是反模式.使用服务位置时,您始终必须在整个架构中主动调用服务定位器.所以你要解耦你的课程,但另一方面你将它们全部联系到服务定位器.此外,使用服务定位器进行依赖性发现更加困难,因为您隐藏了依赖项.而使用依赖注入,您可以使用构造函数注入使依赖项"公开".
使用IoC容器时,可以使用依赖注入(构造函数注入或属性注入).现在,IoC容器可以通过查看构造函数参数来重新调整依赖关系图,并创建整个依赖关系图.这称为自动布线.服务定位器无法自动连接依赖项.正如我已经提到的,你没有被迫使用自动布线,你可以通过简单地直接在每个类中调用IoC容器来轻松使用像服务定位器这样的IoC容器,但是你不应该!
另见:https://stackoverflow.com/a/11319026/175399
Mik*_*eSW 10
我想您正确理解了服务定位器.
关于依赖注入,意味着如果一个对象具有构造函数和/或属性依赖关系,那么它们会被外部注入到对象中,而不是对象通过它自己获取依赖关系.
public class MyClass
{
private $_dep;
public function __construct($dep=null)
{
//$dep has to be injected
$this->_dep=$dep;
}
//this is wrong because it couples MyClass to a specific Dependency implementation
public function __construct()
{
$this->_dep=new Dependency();
}
}
$dep=new Dependency();
$obj=new MyClass($dep);
Run Code Online (Sandbox Code Playgroud)
通常构造函数将抽象(接口)作为param,并在类外部实例化一个具体的实现,然后在创建MyClass的新实例时将其传递给构造函数.
DI容器,自动处理依赖注入.您只需配置它,以便它知道在提出抽象时要返回的具体类.Container处理对象创建,通过构造函数和/或属性注入依赖项.根据容器(我不知道php的一个例子,我只熟悉.net DI容器)你可能还需要注册它可以创建的对象类型.
控制反转意味着取决于较低级别类(依赖性)实现而不是更高级别类,控制被反转,因此较低级别类实现依赖于较高级别类所需的抽象.
//abstraction defined for the use of higher level class
public interface IRepository {}
// that's the dependency, the lower level class
public class XmlRepository implements IRepository {}
//the higher level class
public class MyClass
{
public function __construct(IRepository $repo) {}
}
Run Code Online (Sandbox Code Playgroud)
DI容器提供IoC功能时,IoC和DiC一起使用.