我已经编程了一段时间但从未对理解每个概念的含义感兴趣,我可能正在使用各种编程概念,但却不知道它。
服务定位器:
对我来说,是指通过减少代码量来加快开发速度的快捷方式记录。 一个问题是:可能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();
依赖注入(和依赖注入容器):
在对象中注入对象,无论工厂模式如何,都可以更快地访问这些对象。 和DI容器?
以下是我对它的理解:
$app = new System\Application(System\Config::load());
控制反转:
不明白这个设计模式(或理解,但不知道我做的是IoC)
然后,在理论上(最好用简单的例子),这些概念中的每一个意味着什么? 我是正确的,还是有什么不对/可以改进?
谢谢!
不确定"快速访问"是什么意思。 全局变量或单例也同样快。 我认为你所谈论的更多是关于模块化的。
当我有一个DI时,整个类被注入到另一个中,所以,我不需要另一个设计模式,因为我在第二课中有我需要的所有东西。 (了解?!)
等一下..谁在这里问问题?:P
我将您的评论解释为一个问题。 (巴西初学者的事)。 你在谈论模块化的问题? 有DI,IoC和服务定位器的关系,你能解释一下吗?
将注射视为松散耦合的一种形式。 不同的模块不必"知道"如何相互访问,而是注入引用。 这使得更改不同模块变得更加容易,而不会破坏您忘记的内容。 它不是一个方便的访问,因为它是一个模块化的方法,为了可持续的代码。
服务位置和依赖注入首先用于解耦类,以便可以轻松地测试和更改它们。
当您比较寄存器并解决IoC容器的部分与服务定位器时,它似乎是相同的。
您可以使用IoC容器作为服务定位器,这被??认为是反模式。使用服务位置时,您始终必须在整个架构中主动调用服务定位器。所以你要解耦你的课程,但另一方面你将它们全部联系到服务定位器。此外,使用服务定位器进行依赖性发现更加困难,因为您隐藏了依赖项。而使用依赖注入,您可以使用构造函数注入使依赖项"公开"。
使用IoC容器时,可以使用依赖注入(构造函数注入或属性注入)。现在,IoC容器可以通过查看构造函数参数来重新调整依赖关系图,并创建整个依赖关系图。这称为自动布线。服务定位器无法自动连接依赖项。
正如我已经提到的,你没有被迫使用自动布线,你可以通过简单地直接在每个类中调用IoC容器来轻松使用像服务定位器这样的IoC容器,但是你不应该!
另见:https://stackoverflow.com/a/11319026/175399
图片+1为P
我完全不了解IoC。你可以发一些样品吗?
非常好的答案。
@GabrielSantos我只能发布.NET的例子。
谢谢@Rookian,但不理解.NET = P.
说实话,我有类似的问题 - 我有服务定位器(反模式),我想我理解DI,但从我的观点来看,IoC是DI或服务定位器 - 取决于它是如何用过的。从我的观点来看,IoC组由可能的实现组成:服务定位器或DI ......虽然我是一个PHP开发人员,但我做了一点.NET(C#),我想我可以使用你的.NET的IoC示例你仍然觉得要提供它们......谢谢! ;-)
完全是@shadyyx。这有点令人困惑,因为人们会说DI容器或IoC容器。该框架是一个IoC容器,主要用作DI工具。就个人而言,我倾向于称它为DI容器:)
我想您正确理解了服务定位器。
关于依赖注入,意味着如果一个对象具有构造函数和/或属性依赖关系,那么它们会被外部注入到对象中,而不是对象通过它自己获取依赖关系。
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);
通常构造函数将抽象(接口)作为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) {}
}
DI容器提供IoC功能时,IoC和DiC一起使用。
很好的解释。那么,DI谈论注入一个对象并存储在你注入的类中,以便将来访问?
关于IoC,不太了解,如果你能解释得更多,我感谢你。
关于DI,是的。关于IoC,我不知道如何更好地解释它,但是每当一个类指定它需要抽象作为依赖时,那就是IoC模式。