PHP学习笔记2——设计模式
概念
设计模式(Design Pattern):是一套反复被使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
- 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
常用的设计模式
- 单例设计模式:一个类只能创建一个实例对象,不管用什么办法都无法创建第2个对象;
- 工厂设计模式:生产不同类对象的工厂;
- 策略设计模式:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换;
- 观察者设计模式:定义对象间一种一对多的依赖关系使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
单例设计模式
单例设计模式的要求
三私一公:
- 私有的静态的保存对象的属性
- 私有的构造方法,阻止类外new对象
- 私有的克隆方法,阻止类外clone对象
- 共有的静态的创建对象的方法
单例设计模式的核心代码:
<?php
//单例设计模式的核心代码
class Db
{
//私有的静态的保存对象的属性
private static $obj=null;
//私有的构造方法:阻止类外new对象
private function __construct()
{
}
//私有的克隆方法:阻止类外clone对象
private function __clone(){}
//公共的静态的创建对象的方法
public static function getInstance()
{
//判断当前对象是否存在
if(!self::$obj instanceof self)
{
//如果对象不存在,并保存它
self::$obj=new self();
}
//返回对象
return self::$obj;
}
}
//创建数据库类的对象
$db1=Db::getInstance();
$db2=Db::getInstance();
var_dump($db1,$db2);
数据库工具类(./libs/Db.class.php)
<?php
//定义最终的单例的数据库工具类
class Db
{
//私有的静态的保存对象的属性
private static $obj=null;
//私有的数据库配置信息
private $db_host;//主机名
private $db_user;//用户名
private $db_pass;//密码
private $db_name;//数据集名
private $charset;//字符集
private $link; //连接对象
//私有的构造方法:阻止类外new对象
private function __construct($config=array())
{
$this->db_host=$config['db_host'];
$this->db_user=$config['db_user'];
$this->db_pass=$config['db_pass'];
$this->db_name=$config['db_name'];
$this->charset=$config['charset'];
$this->connectDb();//连接mysql服务器
$this->selectDb();//选择数据库
$this->setCharset();//设置字符集
}
//私有的克隆方法:阻止类外clone对象
private function __clone(){}
//公共的静态的创建对象的方法
public static function getInstance($config=array())
{
//判断当前对象是否存在
if(!self::$obj instanceof self)
{
//如果对象不存在,并保存它
self::$obj=new self($config);
}
//返回对象
return self::$obj;
}
//私有的连接mysql服务器方法
private function connectDb()
{
if(!$this->link=@mysqli_connect($this->db_host,$this->db_user,$this->db_pass))
{
echo "连接mysql服务器失败!";
die();
}
}
//私有的选择数据库的方法
private function selectDb()
{
if(!mysqli_select_db($this->link,$this->db_name))
{
echo "选择数据库{$this->db_name}失败!";
die();
}
}
//私有的设置字符集
private function setCharset()
{
mysqli_set_charset($this->link,$this->charset);
}
//公共的执行SQL的方法:insert 、update、delete、set、drop等
public function exec($sql)
{
//例如:update student set salary=salary+500 where id=5
//将SQL语句转成全小写
$sql=strtolower($sql);
//判断是不是select语句
if(substr($sql,0,6)=='select')
{
echo "不能执行select语句!";
die();
}
//返回执行的结果(布尔值)
return mysqli_query($this->link,$sql);
}
//私有的执行SQL语句的方法:select
//执行成功返回结果集对象,执行失败返回false
private function query($sql)
{
//例如:select * from student
//将SQL语句转成全小写
$sql=strtolower($sql);
//判断是不是select语句
if(substr($sql,0,6)!='select')
{
echo "不能执行非select语句!";
die();
}
//返回执行的结果(结果集)
return mysqli_query($this->link,$sql);
}
//公共的获取单行数据的方法
public function fetchOne($sql,$type=3)
{
//执行SQL语句并返回结果集对象
$result=$this->query($sql);
//定义返回数组类型的常量
$types=array(
1=>MYSQLI_NUM,
2=>MYSQLI_BOTH,
3=>MYSQLI_ASSOC
);
//返回一维数组
return mysqli_fetch_array($result,$types[$type]);
}
//公共的获取多行数据的方法
public function fetchAll($sql,$type=3)
{
//执行SQL语句并返回结果集对象
$result=$this->query($sql);
//定义返回数组类型的常量
$types=array(
1=>MYSQLI_NUM,
2=>MYSQLI_BOTH,
3=>MYSQLI_ASSOC
);
//返回二维数组
return mysqli_fetch_all($result,$types[$type]);
}
//公共的获取记录数
public function rowCount($sql)
{
//执行SQL语句并返回结果集对象
$result=$this->query($sql);
//返回记录数
return mysqli_num_rows($result);
}
//公共的析构方法
private function __destruct()
{
mysqli_close($this->link);//断开mysql连接
}
}
连接数据库的公共文件(./conn.php)
<?php
//类的 类的自动加载
spl_autoload_register(function($className){
//构建类文件的路径
$filename="./libs/$className.class.php";
//如果类文件存在,则包括
if(file_exists($filename))
require_once($filename);
});
//创建数据库类的对象
$arr=array(
'db_host' => 'localhost',
'db_user' => 'root',
'db_pass' => '',
'db_name' => 'itcast',
'charset' => 'utf8'
);
$db=Db::getInstance($arr);
显示学生信息列表(./list.php)
<?php
//包含连接数据库的公共文件
require_once("./conn.php");
//获取多行数据
$sql="select * from student";
$arrs=$db->fetchAll($sql);
//获取记录数
$records=$db->rowCount($sql);
?>
工厂设计模式
概念
- 根据传递不同的类名参数,返回不同类的对象
- 工厂模式,就是生产各种的不同类的对象
- 工厂模式改变了在类外使用new关键字创建对象的方式,改变了在工厂类中创建类的对象
- 在类的外部我们无法控制类的行为,但在类内部自己可以控制类的行为。
工厂设计模式的要求
- 工厂类中的方法,应该是公共的静态的方法;
- 该方法的功能:就是根据传递的不痛痛参数,去创建不通过类的实例。
实例:创建不同形状类的对象
shape.class.php
<?php
//定义形状接口
Interface Shape
{
//绘制方法
public function draw();
}
Circle.class.php
<?php
//定义圆形类,并实现形状接口
class Circle implements Shape
{
//重写draw()方法
public function draw()
{
echo "正在绘制圆形!";
}
}
Rectangle.class.php
<?php
//定义矩形类,并实现形状接口
class Rectangle implements Shape
{
//重写draw()方法
public function draw()
{
echo "正在绘制矩形!";
}
}
Factory.class.php
<?php
//定义形状工厂类:生产不同形状对象的工厂
class Factory
{
//公共的静态的创建不同类对象的方法
public static function getInstance($className)
{
//根据传递的不同类名参数,返回不同类对象
switch($className)
{
case "Rectangle":
return new Rectangle;
break;
case "Circle":
return new Circle;
break;
default:
return null;
}
}
}
app.php
<?php
//类的自动加载
spl_autoload_register(function($className){
//构建类文件的路径
$filename="./libs/$className.class.php";
//如果类文件存在,则包含
if(file_exists($filename))
require_once($filename);
});
//创建矩形对象
$rectangle=Factory::getInstance("Rectangle");
$rectangle->draw();
//创建圆形对象
$circle=Factory::getInstance("Circle");
$circle->draw();