PHP十二种设计模式

PSR-0规范的设计基础

1.全部使用命名空间

2.所有php文件必须自动载入,不能有include/require

spl_autoload_register

3.单一入口模式

1.三种基本的设计模式

工厂模式

用一个工厂方法去替换掉一个new

class Factory{

static function createDatabase(){

$db = new Database;

return $db;

}

}

使用的时候就可以用 $db = Factory::createDatabase();

单例模式

class Database{

private $db;

private function __construct(){

//这里可以写连接数据库

}

static function getInstance(){

if(self::$db){

return self::$db;

}else{

self::$db=new self()

return self::$db;//private可以自身调用

}

}

function where(){

}

}

如果是工厂加单例模式

class Factory{

static function createDatabase(){

$db = Database::getInstance();

return $db;

}

}

注册器(树)模式

class Register{

protected static $object;

static function set($alias,$object){

self::$object[$alias]=$object;

}

static function get($name)

{

return self::$object[$name];

}

function _unset($alias){

unset(self::$object[$alias]);

}

}

跟工厂方法结合

class Factory{

static function createDatabase(){

$db = Database::getInstance();

Register::set(‘db1‘,$db);

return $db;

}

}

索引直接调用

$db = Register::get(‘db1‘);

适配器模式

1.适配器模式,可以将截然不同的函数接口封装成统一的API

2.实际应用举例,PHP的数据库操作有mysql,mysqli,pdo3种,可以用适配器模式

统一成一致,类似的场景还有cache适配器,将memcache,redis,file,apc等不同的缓存函数,统一成一致,

比如说有一个Database.php里面有一个接口

interface IDatabase

{

function connect($host,$user,$pwd,$dbname);

function query($sql);

function close();

}

再下面有三个类

class mysql implements IDatabase{

private $con;

function connect($host,$user,$pwd,$dbname){

$this->con = mysql_connect($host,$user,$pwd);

mysql_select_db($dbname,$this->con);

}

function query($sql){

return mysql_query($sql,$this->con);

}

function close(){

return mysql_close($this->con);

}

}

class mysqli implements IDatabase{

protected $con;

function connect($host,$user,$pwd,$dbname)

{

$this->con = mysqli_connect($host,$user,$pwd,$dbname);

}

function query($sql)

{

return mysqli_query($this->con,$sql);

}

function close()

{

return mysqli_close($this->con);

}

}

class PDO implements IDatabase{

protected $con;

function connect($host,$user,$pwd.$dbname)

{

$con = new \PDO("mysql:host=$host;dbname=$dbname",$user,$pwd);

$this->con=$con;

}

function query($sql){

return $this->con->query($sql);

}

function close(){

unset($this->con);

}

}

这样我们调用的时候

$db = new mysql();或new mysqli();或new PDO();

$db->connect(‘127.0.0.1‘,‘root‘,‘root‘);

$db->query();

$db->close();

策略模式

将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这种模式就是策略模式

实际应用距离,假如一个电商系统的网站系统,针对男性女性用户要各自跳转到不同的商品类别

首先声明一个策略的接口文件

interface UserStrategy{

function showAd();

function showcategory();

}

//第一个策略 针对女性用户

class femaleUserStrategy implements UserStrategy{

function showAd(){

echo ‘2014新款女装‘;

}

function showCategory()

{

echo ‘女装‘;

}

}

//第二个策略,针对于男性用户

class maleUserStrategy implements UserStrategy{

function showAd(){

echo ‘2014新款男装‘;

}

function showCategory()

{

echo ‘男装‘;

}

}

//如果有一个page类

class page{

protected $strategy;

function index(){

$this->strategy->showAd();

$this->strategy->showCategory();

}

function setStrategy(\UserStrategt $strategy){

$this->strategy=$strategy;

}

}

$page = new Page();

if(isset($_GET[‘female‘])){

$strategy = new femaleUserStrategy();

}else{

$strategy = new maleUserStrategy();

}

$page->setStrategy($strategy);

$page->index();

从一个硬编码到解耦的模式

数据对象映射模式

数据对象映射模式,是将对象和数据存储映射起来,对一个

对象的操作会映射为对数据存储的操作。

在代码中实现数据对象映射模式,我们将实现一个ORM类,将复杂的sql语句映射成对象属性的操作

class User{

public $id;

public $name;

public $mobile;

public $regtime;

protected $db;

function __construct($id){

//先取数据

$this->db = new mysql();

$this->db->connect(‘xxxxx‘xxxx);

$res = $this->db->query(‘select * from XXX where id = {$id}‘);

$data = $res->fetch_assoc();

$this->id=$data[‘id‘];

$this->name=$data[‘name‘];

$this->mobile=$data[‘mobile‘];

$this->regtime=$data[‘regtime‘];

return $res;

}

function __destruct(){

//可以作为修改使用

$this->db->query(‘update xx set name={$this->name} mobile={$this->mobile}XXXXX where id = {$this->id}‘);

}

}

$user = new User(1);//1对应数据库中id为一

$user->mobile = ‘155555555‘;

$user->name=‘test‘;

$user->regtime=time();

//在这里没有sql语句.只有对对象的操作

综合运用(工厂模式,注册器模式,适配器模式)

观察者模式

1.观察者模式,当一个对象状态发生改变时,依赖他的对象全部会收到通知,并自动更新。

2.场景:一个事件发生后,要执行一连串更新操作,传统的编程方式,就

是在事件的代码之后直接加入处理逻辑,当更新的逻辑增多之后,代码会变得难以维护,这种方式是耦合的,侵入式的,

增加心的逻辑需要修改事件主体的代码

3.观察者模式实现了低耦合,非侵入式的通知更新机制。

demo

class Event{

function trigger(){

echo "Event";//表示事件发生了

//开始写更新逻辑了

echo ‘逻辑1‘;

echo ‘逻辑2‘;

echo ‘逻辑3‘;

}

}

$event = new Event();//传统的方式是耦合的,侵入式的,

//必须要改源码,所以我们定义一个观察者模式

demo

//在来一个接口

//先来一个基类抽象类

abstract class EventGenerator{

private $observers = array();

function addObserver(Observer$observer){

$this->obervers[]=$oberver;

}

function notify(){

foreach($this->obervers as $observer)

{

$observer->updata();

}

}

}

interface Oberver{

function update($event_info = null);

}

//所以说这个时候我们需要Event类继承这个基类

class Event extends EventGenerator{

function trigger(){

echo "Event";//表示事件发生了

$this->notify();

}

}

class Observer1 implements Observer{

function updata($event_info=null)

{

echo "逻辑一";

}

}

class Oberver2 implements Oberver{

function updata($event_info=null)

{

echo "逻辑二";

}

}

原型模式

1.与工厂模式作用类似,都是用来创建对象

2.与工厂模式的实现不同,原型模式先创建好一个原型

对象,然后通过clone原型对象来创建新的对象,这样就免去了类

创建时重复的初始化操作

3.原型模式适合于大对象的创建,创建一个大对象需要很大的开销,如果每次new就会消耗很大,

原型模式仅仅拷贝内存即可。

假如有一个画布类。new很复杂

我又想使用他两次

这样我们就可以用原型模式解决new的问题,用clone替代new

初始化之后直接clone即可。

装饰器模式

1.装饰器模式,可以动态的添加修改类的功能。

2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的

编程模式,需要写一个子类继承他,并重新实现类的方法。

3.使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性

如果我们有一个画布类。只能打印一个正方形,假如我们想要添加一个颜色

一般是写一个子类,继承那个画布类。

重写产生画布的方法。那我们如果要增加很多功能呢?

是不是要重写很多类?

下面我们用装饰器模式解决这个问题

首先我们先声明一个画布的装饰器的接口

interface DrawDecorator{

function beforeDraw();

function afterDraw();

}

比如我们要修改画布类的draw()方法

所以我们在draw()方法中调用

function draw(){

$this->beforeDraw();

//这里是原来代码的内容

$this->afterDraw();

}

再在画布类中添加一个protected $decorators[]=array();

在添加一个方法,用来接收装饰器接口

function addDecorator(DrawDecorator $decorator){

$this->decorators[]=$decorator;

}

再添加两个调用装饰器的方法

function beforeDraw(){

foreach($this->decorators as $decorator)

{

$decorator->beforeDraw();

}

}

function afterDraw(){

//进行反转,后进先出

$decorators = array_reverse($this->decorators);

foreach($decorators as $decorator)

{

$decorator->afterDraw();

}

}

我们有一个颜色装饰器

class ColorDrawDecorator implements DrawDecorator{

protected $color;

function __construct($color=‘red‘)

{

$this->color= $color;

}

function beforDraw()

{

echo "<div style=‘color:{$this->color};‘>";

}

function afterDraw()

{

echo "</div>"

}

}

在这里就不用去继承去实现了

$a = new canvas();//实例化画布类

$a -> init();//初始化

$a -> addDecorator(new colorDrawDecorator(‘green‘));//添加一个颜色的装饰器类

迭代器模式

1.迭代器模式,在不需要了解内部实现的前提下,遍历yige

聚合对象的内部元素

2.相比传统的编程模式,迭代器模式可以隐藏遍历元素的所需的操作

比如遍历一个数据库,然后拿到所有对象

class Alluser implements Iterator{

protected $ids;

protected $index;//迭代器当前位置

protected $data=array();

//Iterator为迭代器接口

fucntion __construct(){

$db = Factory::getDatabase();

$result = $db->query("selecy id from user");

$this->ids = $db->mysql_fetch_assoc($result);

}

function current(){

//获取当前元素

$id=$this->ids[$this->index][‘id‘];

return Factory::getUser($id);

}

function next(){

//下一个元素

$this->index ++;

}

function valid()

{

//判断是否有数据

return $this->index < count($this->ids);

}

function rewind(){

$this->index=0;//第一步到开头

}

function key(){

//获取当前索引

return $this->index;

}

}

$users = new Alluser();

foreach ($users as $user)

{

var_dump($user);

}

代理模式

1.在客户端与实体之间建立一个代理对象(proxy),客户端对实体进行操作全部委派给代理对象,隐藏实体具体实现细节。

就是写一个

面向对象编程的基本原则

1.单一职责:一个类,只需要做好一件事情

2.开放封闭:一个类,应该是可扩展的,而不可修改的

3.依赖倒置:一个类,不应该强依赖另外一个类,每个类对于另外一个类都是可替换的

4.配置化:尽可能的使用配置,而不是硬编码。

5.面向接口编程:只需要关心接口,不需要关心实现。

MVC架构原理

我们先new 一个Config的对象

$config = new Config(__DIR__.‘/configs‘);

$config[‘controller‘];

那么有一个Config类

class Config implements \ArrayAccess{

//ArrayAccess接口是内置的接口,表示允许数组传值,其中有要实现四个方法

protected $path;

protected $configs=array();

function __construct($path)

{

$this->path=$path;

}

function offsetGet($key){

//获取该配置数组文件名key

if(empty($this->configs[$key]))

//如果原配置文件中不存在该数组文件名,那么就去加载

{

$file_path=$this->path.‘/‘.$key.‘.php‘;//生成加载路径

$config = require $file_path;

$this->config[$key]=$config;

}

return $this->configs[$key];

}

function offsetSet($key,$value)

{

//设置数组的key

}

function offsetExists($key)

{      //检测数组的key是否存在

return isset($this->configs[$key]);

}

function offsetUnset($key)

{    //删除数组的key

}

}

配置文件比如controller.php

<?php

$config = array(

‘home‘=>array(

‘decorator‘=>array(

‘IMooc\Dectorator\Template‘,

),

),

);

配置与设计模式

1.PHP中使用ArrayAccess实现配置文件的加载

2.在工厂方法中读取配置,生成可配置化的对象

3.使用装饰器模式实现权限验证,模板渲染,json串化

4.使用观察者模式实现数据更新事件的一系列更新操作

5.使用代理模式实现数据库的主从自动切换

时间: 2024-11-15 14:34:07

PHP十二种设计模式的相关文章

还需要学习的十二种CSS选择器

在前面的文章中,我们在介绍了<五种你必须彻底了解的CSS选择器>,现在向大家介绍,还需要学习的另外十二种CSS选择器.如果你还没有用过,就好好学习一下,如果你已经熟知了就当是温习. 一.X:link X:visited X:hover X:active 伪类 a:link { color: red; }a:visted { color: purple; } 伪类选择器,visted已被访问过的样式,hover鼠标经过的样式,link未被访问的样式.三种伪类选择器常用于链接,但不是说只适用于链接

nodeType的十二种类型

nodetype的十二种类型 1:元素节点 2:属性节点 3:文本节点 4:CDATA区段 5:实体应用元素 6:实体 7:表示处理指令 8:注释节点 9:最外层的Root element,包括所有其他节点 10:<!DOCTYPE...> 11:文档碎片节点 12:DTD中声明的符号节点

JavaScript中常见的十五种设计模式

在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”. 在JavaScript中并没有类这种概念,JS中的函数属于一等对象,在JS中定义一个对象非常简单(var obj = {}),而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同. 本文基于<JavaScript设计模式与开发实践>一书,用一些例子总结一下JS常见的设计模式与实现方法.文章略长,自备瓜子板凳~ 设计原则 单一职责原则(SRP) 一个对象或方法只做一件事情.如果一个方法承担了过多的职责,那么在

对于未来编程的十二种预测

凝视水晶球,我们试图寻找未来五年中关于编程会发生什么,哪些会激动人心. 技术领域快速变革着,而用于构建这些技术的工具也随之不断发展.如果你不能超越当前的项目,那你就只能在兔子洞里越陷越深了. 为了帮助您呈现一个精彩的未来,我们预测了未来五年内编程领域将进行的颠覆性变革.由于我们的水晶球的主观色彩很浓,以下这些猜想也许并不是普遍适用的,还有一些或许在五年内不能完全实现.有些虽然已成为了现实,但真理的确立不是一蹴而就的. 亲爱的读者,请你快速阅读吧,因为未来将以超越我们认知的速度发展着. 1. GP

MongoDB十二种最有效的模式设计【转】

持续关注MongoDB博客(https://www.mongodb.com/blog)的同学一定会留意到,技术大牛Daniel Coupal 和 Ken W. Alger ,从 今年 2月17 号开始,在博客上持续发表了 如何在MongoDB中设计数据库模式的方法.截止到今日(4月20号),12种模式设计的方法已全部与读者见面.本人认为,此系列文章,总结的非常全面,很多地方有首创性,涵盖的场景也很多,并且有理论总结,也有案例分析.文中分享的很多知识使人"如听仙乐耳暂明",开卷受益,常读

电脑密码的十二种破解方法

日常操作中,我们经常要输入各种各样的密码,例如开机时要输入密码,QQ时也要先输入密码,假如你忘记了这些密码,就有可能用不了机器.打不开文件.不能聊天…… 也许还会造成很大的损失!下面我们就介绍电脑操作中常用密码的破解方法,希望能解你燃眉之急! 一.遗忘了SYSTEM密码如果你遗忘了CMOS设置中的SYSTEM密码,就无法启动机器了,解决的办法只能是:打开机箱,把电池取下.正负极短接,给 CMOS 放电,清除CMOS中的所有内容(当然也就包括密码),然后重新开机进行设置.注意:有些主板设置了CMO

二十四种设计模式:迭代器模式(Iterator Pattern)

迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现在要提供一种方法顺序地访问这个聚合对象中的各个元素. MessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Iterator { /// <summary>

二十四种设计模式:策略模式(Strategy Pattern)

策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,持久化数据在SqlServer数据库中或Xml文件里(两种可互换的算法).由客户端决定使用哪种算法. MessageModel using System; using System.Collections.Generic; using System.Text; na

二十四种设计模式:解释器模式(Interpreter Pattern)

解释器模式(Interpreter Pattern) 介绍给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 示例有一个Message实体类,某个类对它的操作有Get()方法.现在要求用具有某一规则的中文语法来执行这个操作. MessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Interpreter { //