zoukankan      html  css  js  c++  java
  • 设计模式

    # 设计模式  老程序员 整理  经常遇到的问题  一些通用解决方案

    单例模式:

    三私一公

    1. _instance必须声明为静态的私有变量
    2. 构造函数和析构函数必须声明为私有,防止外部程序new 类从而失去单例模式的意义
    3. getInstance()方法必须设置为公有的,必须调用此方法 以返回实例的一个引用
    4. ::操作符只能访问静态变量和静态函数
    5. new对象都会消耗内存
    6. 使用场景:最常用的地方是数据库连接,系统配置。
    7. 使用单例模式生成一个对象后, 该对象可以被其它众多对象所使用。
    8. 私有的__clone()方法防止克隆对象

    单例模式,使某个类的对象仅允许创建一个。构造函数private修饰, 
    申明一个static getInstance方法,在该方法里创建该对象的实例。如果该实例已经存在,则不创建。比如只需要创建一个数据库连接。

    <?php
    class Explame {
        private  static $intance;
        private  function __construct()
        {
            echo "aa";
        }
        public static function getInstance()
        {
            if (!isset(self::$intance)){
                $c = __CLASS__;
                self::$intance = new $c;
            }
            return self::$intance;
        }
        private function __clone()
        {
            // TODO: Implement __clone() method.
            trigger_error('错误',E_USER_ERROR);
        }
        public function  test(){
            echo '单例';
        }
    
    }
    ?>

    工厂模式

    工厂模式,工厂方法或者类生成对象,而不是在代码中直接new。 
    使用工厂模式,可以避免当改变某个类的名字或者方法之后,在调用这个类的所有的代码中都修改它的名字或者参数。

    ## 工厂模式
    
    namespace factory;
    /**
     * 需要短信发送组件   有两种接口   1、阿里云   2、56短信
     * @author jack
     */
    abstract class Message {
    
        abstract public function send($mobile,$message);
    }
    Class Alidayu extends Message
    {
        public function send($mobile,$message){}
    }
    Class SMS56 extends Message
    {
        public function send($mobile,$message){}
    }
    
    
    ####################################################
    
    
    $rest = (new Alidayu())->send('18612345698','xxxxx');
    # 问题 我项目当中有50多处 都发送了短信  1/工作量巨大   2、测试工作量也大
    
    /**
     * @author Jack
     */
    class MessageFactory
    {
        protected static $msgType = [
            'alidayu' => 'Alidayu',
            '56'      => 'SMS56'
        ];
    
        /**
         * 生成对象
         * @param string $name
         * @throws Exception
         * @return Object
         */
        public static function createMessage( $name )
        {
            if (! array_key_exists($name, self::msgType)) {
                throw new Exception("$name not exist");
            }
            $className = self::msgType[$name];
            return new $className();
        }
    }
    
    
    $rest = MessageFactory::createMessage('alidayu')->send('18612345678','xxxxx');

    观察者模式

    1:观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。 
    2:场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。 
    3:观察者模式实现了低耦合,非侵入式的通知与更新机制

    <?
    # 被观察者接口
    interface Observable{
        public function addObserver($ob);//添加观察者
        public function delObserver($ob);//删除观察者
        public function event();//被观察事件
    }
    
    # 观察者接口
    interface Observer{
        public function Response();
    }
    
    # 被观察者:小明刷卡
    Class Sk implements Observable
    {
        protected $observer = [];
        public function addObserver($ob)
        {
            if(!in_array($ob,$this->observer)){
                $this->observer[] = $ob;
            }
        }
        public function delObserver($ob)
        {
            // TODO: Implement delObserver() method.
        }
        public function event()
        {
            foreach ($this->observer as $ob){
                $ob->Response();
                echo '<hr>';
            }
        }
    }
    
    # 观察者:老妈
    class Mom implements Observer
    {
        public function Response()
        {
            echo "老妈就电话给他 叫他别乱花钱,要什么东西妈给买";
        }
    }
    # 观察者:女友
    class GirlFriend implements Observer
    {
        public function Response()
        {
            echo "女友:赶紧带着我的限量款口红回来";
        }
    }
    # 观察者:姐姐
    class Sister implements Observer
    {
        public function Response()
        {
            echo "姐姐:给我买了没有";
        }
    }
    
    $sk = new Sk();
    
    $sk->addObserver(new Mom());
    $sk->addObserver(new GirlFriend());
    $sk->addObserver(new Sister());
    
    $sk->event();
    
    
    
    ?>

    策略模式

    策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。 
    eg:假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告。在传统的代码中,都是在系统中加入各种if else的判断,硬编码的方式。如果有一天增加了一种用户,就需要改写代码。使用策略模式,如果新增加一种用户类型,只需要增加一种策略就可以。其他所有的地方只需要使用不同的策略就可以。 
    首先声明策略的接口文件,约定了策略的包含的行为。然后,定义各个具体的策略实现类。

    UserStrategy.php
    <?php
    /*
     * 声明策略文件的接口,约定策略包含的行为。
     */
    interface UserStrategy
    {
        function showAd();
        function showCategory();
    }
    FemaleUser.php
    <?php
    require_once 'Loader.php';
    class FemaleUser implements UserStrategy
    {
        function showAd(){
            echo "2016冬季女装";
        }
        function showCategory(){
            echo "女装";
        }
    }
    MaleUser.php
    <?php
    require_once 'Loader.php';
    class MaleUser implements UserStrategy
    {
        function showAd(){
            echo "IPhone6s";
        }
        function showCategory(){
            echo "电子产品";
        }
    }
    Page.php//执行文件
    <?php
    require_once 'Loader.php';
    class Page
    {
        protected $strategy;
        function index(){
            echo "AD";
            $this->strategy->showAd();
            echo "<br>";
            echo "Category";
            $this->strategy->showCategory();
            echo "<br>";
        }
        function setStrategy(UserStrategy $strategy){
            $this->strategy=$strategy;
        }
    }
    
    $page = new Page();
    if(isset($_GET['male'])){
        $strategy = new MaleUser();
    }else {
        $strategy = new FemaleUser();
    }
    $page->setStrategy($strategy);
    $page->index();

    适配器模式

    将各种截然不同的函数接口封装成统一的API。 
    PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。 
    首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。

    1 接口 IDatabase
    2 <?php
    3 namespace IMooc;
    4 interface IDatabase
    5 {
    6     function connect($host, $user, $passwd, $dbname);
    7     function query($sql);
    8     function close();
    9 }
    MySQL
    <?php
    namespace IMoocDatabase;
    use IMoocIDatabase;
    class MySQL implements IDatabase
    {
        protected $conn;
        function connect($host, $user, $passwd, $dbname)
        {
            $conn = mysql_connect($host, $user, $passwd);
            mysql_select_db($dbname, $conn);
            $this->conn = $conn;
        }
    
        function query($sql)
        {
            $res = mysql_query($sql, $this->conn);
            return $res;
        }
    
        function close()
        {
            mysql_close($this->conn);
        }
    }
    MySQLi
    <?php
    namespace IMoocDatabase;
    use IMoocIDatabase;
    class MySQLi implements IDatabase
    {
        protected $conn;
    
        function connect($host, $user, $passwd, $dbname)
        {
            $conn = mysqli_connect($host, $user, $passwd, $dbname);
            $this->conn = $conn;
        }
    
        function query($sql)
        {
            return mysqli_query($this->conn, $sql);
        }
    
        function close()
        {
            mysqli_close($this->conn);
        }
    }
    PDO
    <?php
    namespace IMoocDatabase;
    use IMoocIDatabase;
    class PDO implements IDatabase
    {
        protected $conn;
        function connect($host, $user, $passwd, $dbname)
        {
            $conn = new PDO("mysql:host=$host;dbname=$dbname", $user, $passwd);
            $this->conn = $conn;
        }
    function query($sql)
        {
            return $this->conn->query($sql);
        }
    
        function close()
        {
            unset($this->conn);
        }
    }

    通过以上案例,PHP与MySQL的数据库交互有三套API,在不同的场景下可能使用不同的API,那么开发好的代码,换一个环境,可能就要改变它的数据库API,那么就要改写所有的代码,使用适配器模式之后,就可以使用统一的API去屏蔽底层的API差异带来的环境改变之后需要改写代码的问题。

     
  • 相关阅读:
    userInteractionEnabled
    shareInstance
    UISearchBar
    IOS开发之UIView总结1
    IOS Table中Cell的重用reuse机制分析
    显示/隐藏Mac隐藏文件
    iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear的区别及用途
    2020/4/7
    2020/4/6
    2020/4/4
  • 原文地址:https://www.cnblogs.com/vilucky/p/12425000.html
Copyright © 2011-2022 走看看