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

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

  • 相关阅读:
    大数据处理系列之(二)系统过载保护
    大数据处理系列之(一)Java线程池使用
    js实现递归菜单无限层
    treeTable实现排序
    spring-dm 一个简单的实例
    Equinox OSGi服务器应用程序的配置步骤 (支持JSP页面)
    Spring DM 2.0 环境配置 解决Log4j问题
    Spring.DM web开发环境搭建
    STL容器的排序
    排序例子
  • 原文地址:https://www.cnblogs.com/two-bees/p/10596158.html
Copyright © 2011-2022 走看看