码迷,mamicode.com
首页 > 其他好文 > 详细

策略模式

时间:2019-03-25 20:41:57      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:控制反转   class   struct   阿迪达斯   女性   弹性   编码   增加   实践   


策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,达到承上启下的作用。使用策略模式,能够极大地简化代码使其更优雅、更易于维护,降低了类与类之间的耦合。

eg:假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告。在传统的代码中,都是在系统中加入各种if else的判断,硬编码的方式。如果有一天增加了一种用户,就需要改写代码。使用策略模式,如果新增加一种用户类型,只需要增加一种策略就可以。其他所有的地方只需要使用不同的策略就可以。 

约定用户行为:

<?php 
/**
 * 声明策略文件的接口,约定策略模式包含的行为。
 */
interface UserStrategy{
    function showAd();
    function showCategory();
}

?>

具体行为1/2/3:

<?php 

require_once(‘UserStrategy.php‘);
class FemaleUser implements UserStrategy{
    function showAd(){
        echo ‘2016冬季女装‘;
    }

    function showCategory(){
        echo ‘女装‘;
    }
}

?>
<?php 

require_once(‘UserStrategy.php‘);
class ShoeUser implements UserStrategy{
    function showAd(){
        echo ‘2019阿迪达斯‘;
    }
    function showCategory(){
        echo ‘鞋子‘;
    }
}

?>
<?php 

require_once(‘UserStrategy.php‘);
class MaleUser implements UserStrategy{
    function showAd(){
        echo ‘IPhone6s‘;
    }
    function showCategory(){
        echo ‘电子产品‘;
    }
}
?>

执行代码:

<?php 

/**
 * 执行文件
 */
require_once(‘UserStrategy.php‘);
require_once(‘MaleUser.php‘);
require_once(‘FemaleUser.php‘);
require_once(‘ShoeUser.php‘);

class Page{
    protected $strategy;
    //数据显示
    function index(){
        echo ‘AD<br>‘;
        $this->strategy->showAd();
        echo ‘<br>‘;
        echo ‘Category<br>‘;
        $this->strategy->showCategory();
        echo ‘<br>‘;
    }

    //数据生成
    function setStrategy(UserStrategy $strategy){
        $this->strategy = $strategy;
    }
}

$page = new Page();
if($_GET[‘male‘] == ‘1‘){
    echo ‘1<br>‘;
    $strategy = new MaleUser();
}elseif($_GET[‘male‘] == ‘2‘){
    echo ‘2<br>‘;
    $strategy = new FemaleUser();
}else{
    echo ‘3<br>‘;
    $strategy = new ShoeUser();
}
$page->setStrategy($strategy);
$page->index();
?>

  输出

3
AD
2019阿迪达斯
Category
鞋子

 

依赖注入和控制反转:

注入:

简单来说,就是把A类所依赖的B类C类等以属性或者构造函数等方式注入A类而不是直接在A类中实例化。一般写代码我们这样写

class EmailSendByQq {
    public function send(){

    }
}

class User(){
    public function register(){
        $email = new EmailSendByQq();
        $email->send();
    }
}

调用User类的register注册方法,实例化Email类发送邮件。可以看到User类依赖EmailSendByQq类,没有它User类就发送不了邮件,但是如果我们不想用QQ邮箱转而用163(EmailSendBy163)呢,就需要在一个个类中修改EmailSendByQq的实例化,如果使用控制反转对这两个类进行解耦,应该会好一点

class User {
    private $_emailSendObject;
    public function __construct($emailSendObject)
    {
        $this->_emailSendObject = $emailSendObject;
    }
    public function register(){
        $this->_emailSendObject->send();
    }
}

$emailSendObject = new EmailSendByQq;
$user = new User($emailSendObject);
$user->register();

  以属性的方式同样可以实现

class EmailSendBy163 {
    public function send(){

    }
}

class User{
    public $emailSendObject;
    public function register(){
        $this->emailSendObject->send();
    }
}

$user = new User;
$user->emailSendObject = new EmailSendBy163();
$user->register();

 依赖倒置,是一种软件设计思想。传统软件设计中,上层代码依赖于下层代码,当下层出现变动时, 上层代码也要相应变化,维护成本较高。而核心思想是上层定义接口,下层实现这个接口, 从而使得下层依赖于上层,降低耦合度,提高整个系统的弹性。这是一种经实践证明的有效策略。

 

策略模式

标签:控制反转   class   struct   阿迪达斯   女性   弹性   编码   增加   实践   

原文地址:https://www.cnblogs.com/two-bees/p/10596158.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!