现在的位置: 主页 > 商讯 > 文章正文
PHP十二种设计模式
作者:吴桥县齐源纤维素有限公司 来源:www.qy-xws.com 发布时间:2017-09-09 10:32:58
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 "

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:宜昌网站建设 http://yichang.45qun.com


  • 上一篇:SEO执行力?有效执行力?
  • 下一篇:最后一页
  • 
    COPYRIGHT © 2015 吴桥县齐源纤维素有限公司 ALL RIGHTS RESERVED.
    本站所有原创信息,未经许可请勿任意转载或复制使用 网站地图 技术支持:肥猫科技
    精彩专题:网站建设
    购买本站友情链接、项目合作请联系客服QQ:2500-38-100