策略模式(讲解依赖倒置,控制反转,依赖注入)
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
我们简单来理解策略模式,假设我们设计一个机器人,我们对于不同的国家设计出不同的语言模块,这个语言模块就是一个策略。当我们要出厂一个机器人的时候,一开始我们的设计:
//机器人说话模块抽象
interface IRobot
{
function speak();
}
//中文说话模块
class ChinaRobet implements IRobot
{
//override
static function speak(){
echo '你好';
}
}
//日文说话模块
class JapanRobet implements IRobot
{
//override
static function speak(){
echo 'こんにちは';
}
}
//机器人
class Robot
{
//说话方法
function speak(){
if($_GET['China']){
ChinaRobet::speak();
}else if($_GET['Japan']){
JapanRobot::speak;
}
}
}
$robot = new Robot();
$robot->speak();
这样,这个出厂的机器人就拥有了说话的能力。但是呢,由于在每个设定的时候,都要带上两个国家说话模块,(依赖两个类),这样就增加了耦合,并且机器人高层次的依赖于低层次的说话模块。现在我们改一下这个模块:
//机器人
class Robot
{
protect $speakModel;
//说话方法
function speak(){
$this->speakModel->speak();
}
function setModel(IRobot $speakModel)
{
$this->speakModel = $speakModel;
}
}
if($_GET['China']){
$speakModel = new ChinaRobot();
}else if($_GET['Japan']){
$speakModel = new JapanRobot();
}
$robot = new Robot();
$robot->setModel($speakModel);
$robot->speak();
这样的话,在机器人设定的时候,我们不依赖于他底层的模块,只是设定他抽象出来说话的功能。
这样,你装载了什么模块,机器人就在说话功能时做出不一样的处理。这样机器人就不依赖于底层的模块,只去按照抽象接口去实现自己的方法。这就是依赖倒置。
当Robot内部不再需要实例化两个语言模块,自己只关心依赖提供的方法,这就是控制反转。以前是Robot类要实例化并且操作两个语言包,现在只需要实现自己的功能就好了。
依赖注入就更简单啦,你装上模块,将robot依赖的模块通过参数传递进来的方式就是注入。依赖注入