zoukankan      html  css  js  c++  java
  • 策略模式和注入控制反转

    
    

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

    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();

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

  • 相关阅读:
    最长公共子序列
    小测试 炒书
    洛谷P1968 美元汇率
    洛谷P3611 [USACO17JAN]Cow Dance Show奶牛舞蹈
    【刷题】【树】【模拟】树网的核
    【刷题】【dp】地精的贸易
    【刷题】【模拟】复制cs
    【刷题】【模拟】3n+1
    【刷题】【dp】中国象棋
    【刷题】【搜索】新数独
  • 原文地址:https://www.cnblogs.com/two-bees/p/10596158.html
Copyright © 2011-2022 走看看