大粨兔奶糖

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式

1. 学习设计模式的意义

  • 更深入的理解面向对象的思想
  • 有利于开发出扩展性更强的程序, 能够更好的适应需求的变化
  • 面试

2. 设计模式的定义

开发过程中, 典型场景的典型解决方案, 叫做设计模式

举例: 下象棋时, 当头炮, 把马跳

3. 常见设计模式

  • 简单工厂模式

    <?php
    // 服务端代码
    class Phone
    {
    
    }
    
    class Computer
    {
    
    }
    
    class Factory
    {
        public function getPro($pro = '')
        {
            if ($pro == 'phone') {
                return new Phone();
            } elseif ($pro == 'computer') {
                return new Computer();
            } else {
                throw new \Exception('not support');
            }
        }
    }
    // 客户端代码
    $phone = new Factory('phone');
    $computer = new Factory('computer');
    

    思考:

    • 若不使用简单工厂模式, 代码是怎样的?

    • 若不使用简单工厂模式, 带来的后果是怎样?

      若不使用简单工厂模式, 客户端需要知道服务端具体的类来进行实例化, 以后服务端的类有任何的修改, 客户端代码均需要感知并修改代码
      
    • 在思考一个问题: 如果服务器端要新增一个新的产品 Tv, 要怎么办?

      编程的开闭原则: 对于修改是封闭的, 对于扩展是开放的
      
  • 工厂模式

    <?php
    // 服务端
    interface Factory
    {
        public function getPro();
    }
    
    class Phone
    {
    
    }
    
    class Computer
    {
    
    }
    
    class PhoneFactory implements Factory
    {
        public function getPro()
        {
            return new Phone();
        }
    }
    
    class ComputerFactory implements Factory
    {
        public function getPro()
        {
            return new PhoneFactory();
        }
    }
    // 客户端
    $factory = new PhoneFactory();
    $phone = $factory->getPro();
    $factory = new ComputerFactory();
    $computer = $factory->getPro();
    

    思考:

    • 如果服务器新增一个 Tv, 与简单工厂模式相比, 工厂模式有什么区别?
    总结:
    - 简单工厂模式与工厂模式均封装了具体的实例类
    - 工厂模式更适合于服务端进行扩展
    
  • 单例模式 (不想讲了)

  • 策略模式

    定义: 完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务

    有的人的代码是这样实现的:

    // 服务端
    class Choose
    {
        public function goToSchool($strategyName)
        {
            if ($strategyName == 'subwayStrategy') {
                echo '坐地铁去公司';
            } elseif ($strategyName == 'bike') {
                echo '骑自行车去公司';
            } elseif ($strategyName == 'bus') {
                echo '坐公交车去公司';
            } else {
                throw new \Exception('not support');
            }
        }
    }
    // 客户端
    $choose = new Choose();
    $choose->goToSchool('subwayStrategy');
    

    其实好的代码是这样的:

    // 服务器
    abstract class Strategy
    {
        abstract function wayToCompany();
    }
    
    class SubwayStrategy extends Strategy
    {
        public function wayToCompany()
        {
            echo '坐地铁去公司';
        }
    }
    
    class BikeStrategy extends Strategy
    {
        public function wayToCompany()
        {
            echo '骑自行车去公司';
        }
    }
    
    class BusStrategy extends Strategy
    {
        public function wayToCompany()
        {
            echo '坐公交车去公司';
        }
    }
    
    class Choose
    {
        private $strategy = null;
    
        public function getStrategy($strategyName)
        {
            $class = ucfirst($strategyName);
            $this->strategy = new $class;
        }
    
        public function goToSchool()
        {
            $this->strategy->wayToCompany();
        }
    }
    // 客户端
    $choose = new Choose();
    $choose->getStrategy('subwayStrategy');
    $choose->goToSchool();
    

    思考:

    • 策略模式与工厂模式有点像, 工厂模式着眼点在返回操作的对象, 而策略模式着眼点在于执行一系列的程序逻辑
    • 策略模式有一个执行策略的对象类(Choose), 在此类中会通过客户端的需求自行实例化具体策略类, 然后封装策略算法来让客户端调用
    • 举例: 思考一个场景, 你去取快递, 有两种方式
      • 自己去前台询问, 前台告诉你附近的快递站点, 自己去取 (工厂模式)
      • 自己去前台询问, 前台帮你去附近快递站点取, 自己从前台拿 (策略模式)
posted on 2019-01-04 10:15  大粨兔奶糖  阅读(101)  评论(0编辑  收藏  举报