PHP学习笔记2——设计模式

概念

设计模式(Design Pattern):是一套反复被使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

  • 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

常用的设计模式

  • 单例设计模式:一个类只能创建一个实例对象,不管用什么办法都无法创建第2个对象;
  • 工厂设计模式:生产不同类对象的工厂;
  • 策略设计模式:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换;
  • 观察者设计模式:定义对象间一种一对多的依赖关系使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

单例设计模式

单例设计模式的要求

三私一公:

  1. 私有的静态的保存对象的属性
  2. 私有的构造方法,阻止类外new对象
  3. 私有的克隆方法,阻止类外clone对象
  4. 共有的静态的创建对象的方法

单例设计模式的核心代码:

<?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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值