zoukankan      html  css  js  c++  java
  • 浅谈PHP面向对象编程(九、设计模式)

    9.0 设计模式


      在编写程序时经常会遇到一此典型的问题或需要完成某种特定需求,设计模式就是针对这些问题和需求,在大量的实践中总结和理论化之后优选的代码结构编程风格,以及解决问题的思考方式。

    设计模式就像是经典的棋谱。不同的棋局,使用不同的棋谐,免得自己再去思考和模索。本节将针对PHP应用程序中最常用的两种设计模式进行详细讲解。

    9.1 单例模式


       单例模式是PHP中的一种设计模式,它是指在设计一个类时,需要保证在整个程序运行期间针对该类只存在一个实例对象。

    就像世界上只有一个月亮,假设现在要设计一个类表示月亮,该类只能有一个实例对象,否则就违背了事实。

    在讲解单例设计模式之前,通过一个案例来演示在什么情况时需要使用单例模式,如例9-23 所示

    例9-2

     1 <?php
     2      class dbHelper{
     3          private $conn = null;
     4          public function __construct(){            
     5            //打开一个到 MySQL 服务器的连接
     6            $this->conn = mysql_connect("localhost","root","");
     7            echo "得到一个conn<br/>";
     8         }
     9     }
    10     $db1 = new dbHelper();
    11     $db2 = new dbHelper();
    12     if($db1 === $db2){
    13         echo "一个对象<br/>";
    14     } else {
    15            echo "两个对象<br/>";
    16     }
    17 ?>

    运行结果

    得到一个conn

    得到一个conn

    两个对象

    从上例中可以看出,实例化类dbHelper的两个对象请求的数据库连接是两个不同的连接,而在实际开发中,有时会有这样的需求,

    在一次HTTP 请求中,保证某个类的对象实例只能有一个。这样可以节省资源开销,此时可以使用单例模式。

          单例模式(Singleton)用于为一个类生成一个唯一的对象。(请记住名词    “”三私一公“”)

    私有静态属性

    私有构造方法

    私有克隆方法

    公有静态调用队象方法 

    将上面的dbHelper 类使用单例模式来实现,如例9-24所示

    例9-24

    <?php
        class dbHelper{
            private static $instance = null;//定义一个私有的静态属性$instance
            //声明一个构造方法    
            private function __construct(){
                $this->conn = mysql_connect("localhost","root","");
                echo "得到一个conn<br/>";
            }
            //只有通过这个方法才能返回本类的对象,该方法是静态方法
            public static function getInstance(){
                //如果本类中的$instance为空,说明它还没有被实例化过
                if(self::$instance == null){
                    self::$instance = new self();//实例化本类对象
                }
                return self::$instance;//返回本类的对象
            }
            //阻止用户复制对象实例
            public function __clone(){
            }
        }
        $db1 = dbHelper::getInstance();
        $db2 = dbHelper::getInstance();
        if($db1 === $db2){
            echo "同一个对象";
        }else{
            echo "不是同一个对象";
        }
    ?>

    运行结果

    得到一个conn

    同一个对象

    在上例中,dbHelper类的构造方法使用了private 关键字进行了修饰,即不能在类定义之外使用new来创建对象。

    如此一来就只能通过类 名直接调用getinstance0静态方法来创建对象。在第3行代码声明了一个私有的静态属性$instance.

    将实例化的对象赋值给它,再判断该属性,如果已经有值,就直接返回,如果其值为null, 就先实例化对象,这样就能保证dbHelper类只能被实例化一次。

    最后增加了一个私有的魔术方法_ clone0. 用于防止用户通过clone方法复制对象。

     9.2 工厂模式


    工厂模式的作用就是“生产”对象。工厂方法的参数是要生成对象的类名。

    为了方便理解工厂模式的作用,接下来通过一个案例来演示如何使用工厂模式获取MySQL和sQLite的驱动对象。

    首先在根目录下创建MySQLphp文件。示例代码如下:

    1 <?php
    2     class  MySQL{
    3 
    4              //操作SQL的驱动类
    5 
    6     }

    然后在根目录下创建SQLite.php文件。示例代码如下:

    1 <?php
    2 class SQLite{
    3 
    4 //操作SQLite的驱动类
    5 
    6 }

     最后定义一个工厂方法来获取各驱动对象,代码如例9-25所示

    例9-25

     1 <?php
     2      header('Content-Type: textml;charset=utf-8');
     3      class Db{
     4          //工厂方法
     5          public static function factory($type){
     6            if (include_once  $type . '.php') {
     7                 $classname =  $type;
     8                 return new $classname();
     9            } else {
    10                 echo "出错了!";
    11            }
    12         }
    13     }
    14     //获取MySQL驱动对象
    15     $mysql = Db::factory('MySQL');
    16      //获取SQLite驱动对象
    17     $sqlite = Db::factory('SQLite');
    18     var_dump($mysql);
    19     var_dump($sqlite);
    20 ?>  

     运行结果

    object (MySQL) [1]

    object (SQLite) [2]

    上例中,第5行代码定义了一个静态方法factor(), 这就是工厂方法,该方法的参数为类名。

    第6- 11行代码用于判断类名与参数是否相同,如果相同则创建该类的对象,否则输出“出错了!”。

    第15 17行代码分别调用factory()方法获取对应的驱动对象。

    从运行结果可以看出,工厂方法成功地创建了两个驱动类对象。

  • 相关阅读:
    Linux系统下公式编辑器KLatexFormula
    C++11 std::chrono库详解
    Direct Visual-Inertial Odometry with Stereo Cameras
    改变机器人的初始位姿,让机器人的初始位置不在地图的原点处
    ubuntu为文件添加可执行权限
    oracle的启动和停用
    orcale创建用户、授权
    手工配置oracle数据库
    MySQL存储过程详解 mysql 存储过程
    mysql的navicat执行存储过程
  • 原文地址:https://www.cnblogs.com/lemon-Net-Skill/p/9816354.html
Copyright © 2011-2022 走看看