什么是依赖注入(Dependency Injection)
- 依赖倒置原则:高层模块不应该依赖于低层模块,两个都应该依赖于抽象(接口)。
- 依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高。而依赖倒置原则的思想是,上层不应该依赖下层,应依赖接口。意为上层代码定义接口,下层代码实现该接口,从而使得下层依赖于上层接口,降低耦合度,提高系统弹性。
举个栗子:小霸王游戏机
// 如果使用单纯的面向对象来写
class XiaoBaWang
{
private $game;
public function loadGame()
{
$this->game = new HunDouLuo();
$this->game->play();
}
}
class HunDouLuo{
public function play()
{
//玩游戏
}
}
$machine = new XiaoBaWang();
$machine->loadGame();
class XiaoBaWang
{
private $game;
public function loadGame()
{
$this->game = new Tank();
$this->game->play();
}
}
class Tank
{
public function play()
{
//玩游戏
}
}
$reg = new XiaoBaWang();
$reg->loadGame();
使用依赖注入的写法
小霸王游戏机:插拔式卡带
interface Game
{
public function play();
}
class HunDouLuo implements Game
{
public function play()
{
// 玩魂斗罗
}
}
class Tank implements Game
{
public function play()
{
// 坦克大战
}
}
class XiaoBaWang
{
private $game;
public function __construct(Game $game)
{
$this->game = $game;
}
public function loadGame()
{
$this->game->play();
}
}
$hunDouLuo = new HunDouLuo();
$tank = new Tank();
$machine = new XiaoBaWang($hunDouLuo);
$machine->loadGame();
$machine = new XiaoBaWang($tank);
$machine->loadGame();
上例就使用了"注入"这个思想,就像注射器一样将一个类的实例注入到另一个类的实例中去,需要用什么就注入什么。当然"依赖倒置原则"也始终贯彻在里面。"注入"不仅可以通过构造函数注入,也可以通过属性注入,上面你可以可以通过一个"set"来动态为"game"这个属性赋值。
ioc容器
不过开发中会有这样的经历,一开始类比较少,慢慢的功能越来越多,人员越来越多,编写了很多类,要使用这个类必须先引入那个类,而且一定要确保顺序正确。
于是。。。。
就出现了这样的情况, “a 依赖于b, b 依赖于c, c 依赖于 d, d 依赖于e”, 要获取‘a’的实例,你必须依次引入 ‘e,d,c,b’然后依次进行实例化。维护成本上升,开发成本上升,大家都是接盘侠。
再举一个栗子:游戏平台steam/battle
如果没有游戏平台,几个好友想要联机打魔兽争霸,我们过去是怎么做的?
1.每个人首先一起下载相同版本的游戏
2.安装驱动程序
3.建立/进入 局域互联网络
4.关闭防火墙
5.建房间,进入房间,开始游戏
如果我们玩了一段时间,想换星际争霸玩,那我们需要再来一次以上步骤。
最终,我们玩游戏这个动作是依赖于前面很多步骤的,如果有一步出了错,那么久不能正常开始游戏。
Steam/battle游戏平台做了什么?
当我们在游戏平台上面要一起玩一款游戏时,我们只需要:
1.下载安装游戏平台
2.选择一款游戏使用平台一键安装
3.开始游戏
这时,如果我们要换一款游戏,只需要换个游戏平台一键安装,然后开始游戏,不需要担心和理会之前安装的游戏和开始游戏流程对新游戏有什么影响。
有了以上的思路,我们就可以建一个steam类和游戏类了...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。