php的设计模式
简单工厂
1 <?php 2 interface db{ 3 function conn(); 4 } 5 class dbMysql implements db{ 6 public function conn(){ 7 echo '连接上mysql'; 8 } 9 } 10 11 class dbSqlite implements db{ 12 public function conn(){ 13 echo '连接上sqlite'; 14 } 15 } 16 17 // 简单工厂 18 class Factory { 19 public static function createDb($type = ''){ 20 if($type == 'mysql'){ 21 return new dbMysql(); 22 }else if($type == 'sqlite'){ 23 return new dbSqlite(); 24 }else{ 25 throw new Exception("Error db type", 1); 26 } 27 } 28 } 29 30 // 只对外开放一个Factory::createDb()方法 31 $mysql = Factory::createDb('mysql'); 32 $mysql->conn(); 33 // 如果要新增数据库类型?还要去改代码,如果是java语言改完还要编译,这有多么麻烦 34 // 在面向对象设计法则中,有一个开闭原则,对于修改是封闭,对于扩展是开放的。
工厂模式
<?php interface db{ function conn(); } interface factory{ function createDb(); } class dbMysql implements db{ public function conn(){ echo '连接上mysql'; } } class dbSqlite implements db{ public function conn(){ echo '连接上sqlite'; } } class mysqlFactory implements factory{ public function createDb(){ return new dbMysql(); } } class sqliteFactory implements factory{ public function createDb(){ return new dbSqlite(); } } $fact = new mysqlFactory(); $db = $fact->createDb(); $db->conn();
单例模式
<?php class Single{ protected static $ins = null; public static function getIns() { if(self::$ins === null) { self::$ins = new self(); } return self::$ins; } // 方法 + final 不能被覆盖 class + final 不能被继承 final protected function __construct() {} final protected function __clone() {} } $s1 = Single::getIns(); $s2 = clone $s1; if($s1 === $s2){ echo '是同一个对象'; }else{ echo '不是同一个对象'; }
观察者模式
<?php // php5中提供观察者模式observer与被观察者subject的接口 class User implements SplSubject{ public $login_num; public $observers = null; public $hobby; public function __construct(){ $this->login_num = rand(1, 10); $hobbys = ['running', 'shopping', 'supprot', 'study']; shuffle($hobbys); $this->hobby = $hobbys[0]; $this->observers = new SplObjectStorage(); } public function login(){ echo 'login success'; echo '<br>'; $this->notify(); } public function attach(SPLObserver $observer){ $this->observers->attach($observer); } public function detach(SPLObserver $observer){ $this->observers->detach($observer); } public function notify(){ $this->observers->rewind(); while ($this->observers->valid()) { $observer = $this->observers->current(); $observer->update($this); $this->observers->next(); } } } class safety implements SPLObserver{ public function update(SplSubject $subject){ if($subject->login_num > 3){ echo '您频繁登陆,是否有难言之隐?'.'<br>'; } } } class ad implements SPLObserver{ public function update(SplSubject $subject){ switch ($subject->hobby) { case 'running': echo 'addidas运动裤大折扣'; break; case 'shopping': echo '沃尔玛今日促销'; break; case 'supprot': echo 'NBA总决赛明天开始'; break; case 'study': echo '学习文具优惠'; break; default: # code... break; } } } $user = new User(); $user->attach(new safety()); $user->attach(new ad()); $user->login();
责任链模式
<?php // 责任链模式 class Brand{ private $power = 1; private $higher = 'Admin'; public function process($lev){ if($lev <= $this->power){ echo '版主删帖'; }else{ $higer = new $this->higher; $higer->process($lev); } } } class Admin{ private $power = 2; private $higher = 'Proclie'; public function process($lev){ if($lev >= $this->power){ echo '封号处理'; }else{ $higer = new $this->higher; $higer->process($lev); } } } class Proclie{ public function process(){ echo '请你喝茶'; } } $dange_lever = 2; $judege = new Brand(); $judege->process($dange_lever);
策略模式
<?php interface math{ function calc($first, $last); } class Add implements math{ public function calc($first, $last){ return $first + $last; } } class Sub implements math{ public function calc($first, $last){ return $first - $last; } } class Mul implements math{ public function calc($first, $last){ return $first * $last; } } class Div implements math{ public function calc($first, $last){ return $first / $last; } } // 虚拟计算器 class CMath{ protected $calc = null; function __construct($calc){ $this->calc = new $calc; } public function calc($first, $last){ return $this->calc->calc($first, $last); } } $cmath = new CMath('Sub'); echo $cmath->calc(3, 2);
适配器模式
<?php // 服务端 class Weather{ public static function show(){ $today = ['tep' => 28, 'wind' => 7, 'sun' => 'sunny']; return serialize($today); } } // 增加一个适配器 class AdapterWeather extends Weather{ public static function show(){ $today = parent::show(); $today = json_encode(unserialize($today)); return $today; } } // 客户端 $data = unserialize(Weather::show()); echo '今天温度'.$data['tep'].'度'.',天气:'.$data['sun'].'<br>'; // 如果一个android端,访问这个接口,但是不认识php串行字符串,还要去改服务端改为返回json格式,而且还要顺便客户端也要顺便改,这样子很麻烦,我们可以使用适配器模式 // 假设 java客户端 $data = json_decode(AdapterWeather::show(),true); echo '今天温度'.$data['tep'].'度'.',天气:'.$data['sun'].'<br>';
桥接模式
<?php abstract class Info{ // 发射器 protected $send = null; public function __construct($send){ $this->send = $send; } abstract public function msg($content); public function send($to, $content){ $content = $this->msg($content); $this->send->send($to, $content); } } class zn{ public function send($to, $content){ echo 'zn站内给'.$to.'内容是'.$content; } } class sms{ public function send($to, $content){ echo 'sms站内给'.$to.'内容是'.$content; } } class email{ public function send($to, $content){ echo 'email站内给'.$to.'内容是'.$content; } } class commoninfo extends Info{ public function msg($content){ return '普通信息:'.$content; } } class warninfo extends Info{ public function msg($content){ return '紧急信息:'.$content; } } class dangeinfo extends Info{ public function msg($content){ return '特急信息:'.$content; } } $commoninfo = new commoninfo(new zn()); $commoninfo->send('小明','吃鸡了');
装饰模式
<?php // 装饰器模式做文章修饰功能 class BaseArt { protected $content; protected $art; public function __construct($content) { $this->content = $content; } public function decorator(){ return $this->content; } } class BianArt extends BaseArt{ public function __construct($art) { $this->art = $art; $this->decorator(); } public function decorator() { return $this->content = $this->art->decorator(). '小编摘要'; } } class SeonArt extends BaseArt{ public function __construct($art) { $this->art = $art; $this->decorator(); } public function decorator() { return $this->content = $this->art->decorator(). '加上seo关键词'; } } $ba = new SeonArt(new BianArt(new BaseArt('天天向上'))); echo $ba->decorator();