设计模式在php开发中用途还是非常多,能够使用设计模式并准确选择设计模式将事半功倍的提高开发效率,而且也能提高代码可读性和提升代码解耦度,非常方便以后我们在迭代功能的时候的扩展与重构,不至于看到自己以前写的代码无所适从。
1、单例模式
单例模式:即一个类只被实例化一次,当其他人对其再次实例化时,返回第一次实例化的对象,可以避免大量的new
操作,减少资源的消耗,典型应用于数据库类的实例化。
特点:三私一公 (私有静态属性instance,私有构造方法,私有克隆方法,公有化静态方法getInstance)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?php
class Singleton { private static $instance; private function __construct(){} public static function getInstance(){ if (!isset(self::$instance)) { self::$instance = new self; } return self::$instance; } private function __clone(){}
public function say() { echo "这是用单例模式创建对象实例 <br>"; } public function operation() { echo "这里可以添加其他方法和操作 <br>"; } }
$shiyanlou = Singleton::getInstance(); $shiyanlou->say(); $shiyanlou->operation();
$newShiyanlou = Singleton::getInstance(); var_dump($shiyanlou === $newShiyanlou);
|
2、工厂模式
工厂模式解决的是如何不通过new建立实例对象的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| <?php
interface TV { public function open(); public function close(); }
class XiaomiTv implements TV {
public function open() { echo "open 小米 TV <br>"; }
public function close() { echo "close 小米 TV <br>"; }
}
interface PC { public function work(); public function paly(); }
class LenovoPc implements PC {
public function work() { echo "I‘m working on lenovo computer <br>"; }
public function paly() { echo "Lenovo computer can be use to paly games <br>"; } }
abstract class Factory { abstract public static function createPc(); abstract public static function createTv(); }
class ProductFactory extends Factory { public static function createTv { return new HaierTv(); }
public static function createPc() { return new LenovoPc(); } }
$newTv = ProductFactory::createTv(); $newTv->open(); $newTv->close();
$newPc = ProductFactory::createPc(); $newPc->work(); $newPc->paly();
|
3、策略模式
针对一组算法,将每一个算法封装到具有共同接口的独立的类中,例如进入个人主页时,根据浏览者的不同,给予不同的显示与操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
interface UserStrategy { function showAd(); function showCategory(); }
class FemaleUser implements UserStrategy { function showAd(){ echo "2016冬季女装"; } function showCategory(){ echo "女装"; } }
class MaleUser implements UserStrategy { function showAd(){ echo "IPhone6s"; } function showCategory(){ echo "电子产品"; } }
|
4、适配器模式
将各种截然不同的函数接口封装成统一的API。
PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。
类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。
首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。
1 2 3 4 5 6
| interface IDatabase { function connect($host, $user, $passwd, $dbname); function query($sql); function close(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class MySQL implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysql_connect($host, $user, $passwd); mysql_select_db($dbname, $conn); $this->conn = $conn; }
function query($sql) { $res = mysql_query($sql, $this->conn); return $res; }
function close() { mysql_close($this->conn); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class MySQLi implements IDatabase { protected $conn;
function connect($host, $user, $passwd, $dbname) { $conn = mysqli_connect($host, $user, $passwd, $dbname); $this->conn = $conn; }
function query($sql) { return mysqli_query($this->conn, $sql); }
function close() { mysqli_close($this->conn); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class PDO implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd); $this->conn = $conn; } function query($sql) { return $this->conn->query($sql); }
function close() { unset($this->conn); } }
|
5、注册模式
注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php
class Register { protected static $objects; function set($alias,$object)//将对象注册到全局的树上 { self::$objects[$alias]=$object; } static function get($name){ return self::$objects[$name]; } function _unset($alias) { unset(self::$objects[$alias]); } }
|
6、观察者模式
1:观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
2:场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| <?php
interface Observer { public function update($obj); }
class Message implements Observer {
function update($obj) { echo '发送新订单短信(' . $obj->mobile . ')通知给商家!'; }
}
class Goods implements Observer {
public function update($obj) { echo '修改商品' . $obj->goodsId . '的库存!'; }
}
class Order { private $observers = []; public function attach($ob) { $this->observers[] = $ob; }
public function detach($ob) { $position = 0; foreach ($this->observers as $ob) { if ($ob == $observer) { array_splice($this->observers, ($position), 1); } ++$position; } } public function notify($obj) { foreach ($this->observers as $ob) { $ob->update($obj); } } public function sale() { $obj = new stdClass(); $obj->mobile = '13888888888'; $obj->goodsId = 'Order11111111'; $this->notify($obj); } }
$message = new Message(); $goods = new Goods(); $order = new Order(); $order->attach($message); $order->attach($goods);
$order->sale();
|