9.0 设计模式


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

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

9.1 单例模式


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

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

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

例9-2

 <?php
class dbHelper{
private $conn = null;
public function __construct(){
//打开一个到 MySQL 服务器的连接
$this->conn = mysql_connect("localhost","root","");
echo "得到一个conn<br/>";
}
}
$db1 = new dbHelper();
$db2 = new dbHelper();
if($db1 === $db2){
echo "一个对象<br/>";
} else {
echo "两个对象<br/>";
}
?>

运行结果

得到一个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文件。示例代码如下:

 <?php
class MySQL{ //操作SQL的驱动类 }

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

 <?php
class SQLite{ //操作SQLite的驱动类 }

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

例9-25

 <?php
header('Content-Type: textml;charset=utf-8');
class Db{
//工厂方法
public static function factory($type){
if (include_once $type . '.php') {
$classname = $type;
return new $classname();
} else {
echo "出错了!";
}
}
}
//获取MySQL驱动对象
$mysql = Db::factory('MySQL');
//获取SQLite驱动对象
$sqlite = Db::factory('SQLite');
var_dump($mysql);
var_dump($sqlite);
?>

运行结果

object (MySQL) [1]

object (SQLite) [2]

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

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

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

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

浅谈PHP面向对象编程(九、设计模式)的更多相关文章

  1. 浅谈python面向对象编程和面向过程编程的区别

    面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步步实现,使用的时候再一个个的依次调用即可. 优点:性能高 缺点:相较于面向对象而言,不易维护,不易复用,不易扩展 适合于小型的项目面向对象 ...

  2. 浅谈PHP面向对象编程(二、基础知识)

    和一些面向对象的语言有所不同,PHP并不是一种纯面向对象的语言,包PIP它支持面向对象的程序设计,并可以用于开发大型的商业程序.因此学好面向对象输程对PHP程序员来说也是至关重要的.本章并针对面向对象 ...

  3. 浅谈PHP面向对象编程(一、简介)

    传统的面向过程 将要完成的工作,分作若干个步骤,或再细分为子步骤,然后后步骤从前往后一步一步完成,最初达致目标. 现代的面向对象 将要完成的工作拆分为“一个一个对象”的任务(功能),每个对象独自完成自 ...

  4. 浅谈PHP面向对象编程(八、多态)

    8.0  多态 在设计一个成员方法时,通常希望该方法具备一定的通用性.例如要实现一个动物叫的方法,由于每个动物的叫声是不同的,因此可以在方法中接收-个动物类型的参数的对象当传人猫类对象时就发出猫类的叫 ...

  5. 浅谈PHP面向对象编程(七、抽象类与接口)

    7.0 抽象类与接口 当定义一个类时,常常需要定义一些方法来描述该类的行为特征.但有时这些方法的实现方式是无法确定的,此时就可以使用抽象类和接口. 抽象类和接口用于提高程序的灵活性.抽象类是一种特殊的 ...

  6. 浅谈PHP面向对象编程(六、自动加载及魔术方法)

    6.0 自动加载及魔术方法  6.1 自动加载 在PHP开发过程中,如果希望从外部引入一个class.通常会使用incluae和requre方法把定义这个class的文件包含进来.但是,在大型的开发项 ...

  7. 浅谈PHP面向对象编程(五、继承)

    5.0 继承 5.1 继承的概念 在现实生活中,继承一般指的是子女继承父辈的财产.在程序中,继承描述的是事物之间的所属关系,通过继承可以使许多事物之间形成一种关系体系 . 例如猫和狗都属于动物,程序中 ...

  8. 浅谈PHP面向对象编程(四、类常量和静态成员)

    4.0 类常量和静态成员 通过上几篇博客我们了解到,类在实例化对象时,该对象中的成员只被当前对象所有.如果希望在类中定义的成员被所有实例共享. 此时可以使用类常量或静态成员来实现,接下来将针对类常量和 ...

  9. 浅谈PHP面向对象编程(三、构造方法和析构方法)

    3.0 构造方法和析构方法 从我之前的博客可以发现,实例化一个类的对象后,如果要为这个对象的属性赋值,需要直接访问该对象的属性.如果想要在实例化对象的同时就为这个对象的属性进行赋值,则可以通过构造方法 ...

随机推荐

  1. c# 自定义排序类(冒泡、选择、插入、希尔、快速、归并、堆排序等)

    using System; using System.Text; namespace HuaTong.General.Utility { /// <summary> /// 自定义排序类 ...

  2. poscms基于list标签实现的查询分页功能

    poscms系统本身有一个在查询页(search页面)实现的查询分页功能,基于系统封装的php函数dr_search_url() 但是今天的需求除了导航栏.列表页.详情页都实现查询功能外,关键是有两个 ...

  3. [AirFlow]AirFlow使用指南一 安装与启动

    1. 安装 通过pip安装: xiaosi@yoona:~$ pip install airflow 如果速度比较慢,可以使用下面提供的源进行安装: xiaosi@yoona:~$ pip insta ...

  4. C# 加密狗 超级狗 加密程序 程序授权示例 程序授权验证

    本篇针对超级狗进行讲解,对应的超级狗套件的工具包版本为2.4版本.超级狗图片如下: 主要包含两个狗,一个是超级狗,一个是开发狗,在本博文中都是必须的.首先先安装光盘中的开发套间. 接下来就开始演示一个 ...

  5. 使用TR1的智能指针

    作为C++程序员,在没有智能指针,手动管理内存的蛮荒岁月里,可以说是暗无天日,痛苦异常.直到上帝说,还是要有光,于是智能指针进了标准.C++码农的日子总算好起来了. 虽然一直鄙视着没有显式指针的语言, ...

  6. Wireshark小技巧

    抓头部: 时间格式设置: 自定义颜色: 快速过滤TCP/UDP: 过滤一个TCP/UDP Stream: 根据感兴趣内容生成表达式:如果右击的是Apply as Filter则生成表达式并自动执行

  7. Why I am not afraid of AI (TBC)

    Freud! Yes, according to Freud's theory, most human activities are driven by libido (or aim-inhibite ...

  8. hexo+github部署

    废话不多少,接着上次配置的环境进行github部署. 拥有自己的github 如果还没有github的账号就注册一个吧,传送门:GitHub官网:http://www.github.com 创建一个创 ...

  9. Java并发--Thread类详情

    以下是本文的目录大纲: 一.线程的状态 二.上下文切换 三.Thread类中的方法 转载原文链接:http://www.cnblogs.com/dolphin0520/p/3920357.html 一 ...

  10. stm32寄存器版学习笔记05 PWM

    STM32除TIM6和TIM7外都可以产生PWM输出.高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出. 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟 ...