视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
php控制反转怎么实现的
2020-11-27 15:20:07 责编:小采
文档
IoC,控制反转(Inversion of Control),依赖关系的转移,依赖抽象而非实践

DI,依赖注入(Dependency Injection),不必自己在代码中维护对象的依赖,容器自动根据配置,将依赖注入指定对象

某地区有各种不同的商店,每家商店都卖四种水果:苹果十元一个、香蕉二十元一个、橘子三十元一个、西瓜四十元一个,顾客可以在任意商店进行购买,每家商店需要可以随时向税务局提供总销售额。(推荐学习:PHP编程从入门到精通)

初步代码实现

class Shop
{
// 商店的名字
private $name;

// 商店的总销售额
private $turnover = 0;

public function __construct($name){
$this->name = $name;
}

// 售卖商品
public function sell($commodity){
switch ($commodity){
case 'apple':
$this->turnover += 10;
echo "卖出一个苹果<br/>";
break;
case 'banana':
$this->turnover += 20;
echo "卖出一个香蕉<br/>";
break;
case 'orange':
$this->turnover += 30;
echo "卖出一个橘子<br/>";
break;
case 'watermelon':
$this->turnover += 40;
echo "卖出一个西瓜<br/>";
break;
}
}
// 显示商店目前的总销售额
public function getTurnover(){
echo $this->name.'目前为止的销售额为:'.$this->turnover;
}
}

// 顾客类
class Human
{
//从商店购买商品
public function buy(Shop $shop,$commodity){
$shop->sell($commodity);
}
}

// new一个名为kfc的商店
$kfc = new Shop('kfc');
// new一个名为mike的顾客
$mike = new Human();

// mike从kfc买了一个苹果
$mike->buy($kfc,'apple');
// mike从kfc买了一个香蕉
$mike->buy($kfc,'banana');

//

输出kfc的总营业额
echo $kfc->getTurnover();

可以看到,虽然代码完成了对目前需求的实现,但是此时的 shell() 方法依赖于具体的实践并且拥有绝对的控制权。一旦我们需要在商店加入一个新的商品,比如芒果mango,那我们不得不去修改商店类的 sell() 方法,违反了 OCP 原则,即对扩展开放,对修改关闭。

此时我们可以修改代码如下

abstract class Fruit
{
public $name;
public $price;
}
class Shop
{
//商店的名字
private $name;

//商店的总销售额
private $turnover = 0;

public function __construct($name){
$this->name = $name;
}

//售卖商品
public function sell(Fruit $commodity){
$this->turnover += $commodity->price;
echo '卖出一个'.$commodity->name.',收入'.$commodity->price."元<br/>";
}

//显示商店目前的总销售额
public function getTurnover(){
echo $this->name.'目前为止的销售额为:'.$this->turnover;
}
}

//顾客类
class Human
{
//从商店购买商品
public function buy(Shop $shop,$commodity){
$shop->sell($commodity);
}
}

class Apple extends Fruit
{
public $name = 'apple';
public $price = 10;
}
class Bananae extends Fruit
{
public $name = 'banana';
public $price = 20;
}
class Orange extends Fruit
{
public $name = 'orange';
public $price = 30;
}
class Watermelon extends Fruit
{
public $name = 'watermelon';
public $price = 40;
}

//new一个名为kfc的商店
$kfc = new Shop('kfc');
//new一个名为mike的顾客
$mike = new Human();

//mike从kfc买了一个苹果
$mike->buy($kfc,new Apple());
//mike从kfc买了一个香蕉
$mike->buy($kfc,new Bananae());

//

输出kfc的总营业额
echo $kfc->getTurnover();

上面的代码增加了一个名为 Fruit 的抽象类,所有的水果都成不同的继承了 Fruit 的类,此时 sell() 方法不再依赖具体的水果名,而是依赖于抽象的 Fruit 类,决定卖了多少钱的控制权不再包含在方法内,而是由方法外传入,这就是控制反转,而实现控制反转的过程就是依赖注入。

通过控制反转,对象在被创建的时候,由一个系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

下载本文
显示全文
专题