内容简介:PHP_设计模式
什么是设计模式
在软件开发过程中,经常出现的经典场景的典型解决方案,称为设计模式
如何学习设计模式
典型场景 --> 典型问题 --> 典型解决办法
多态
用来消除逻辑语句.
多态(ploymorphism)是一个生物学上的概念,指同一特种的多种表现形态.
在面向对象中,指某种对象实例的不同表现形态.
<?php abstract class Tiger { public abstract function climb(); } class XTiger extends Tiger { public function climb() { echo 'Drop' , '<br/>'; } } class MTiger extends Tiger { public function climb() { echo 'Up' , '<br/>'; } } class Cat { public function climb() { echo 'Fly'; } } class Client { public static function call(Tiger $animal) { // 参数限定不严格,可以更加灵活, 可以传递一个父类类型,就可以有不同的子类形态 $animal->climb(); } } Client::call(new XTiger()); Client::call(new MTiger()); Client::call(new Cat()); ?>
在23种 设计模式 中,可以有些模式可以自然消除的.
面向接口开发
减少 new
的操作.
熟悉概念:
调用端
的概念
客户端(Client)
的概念
例如:在 Java 中,写了一堆类,最终打成一个包。调用端可以把包引入,然后使用类中定义的方法,在开发过程中可以使用查看里面的方法。
假设:开发中引入的是 sdk
,都不让看。如何调用,必须开放一些接口。存在 面向接口开发
接口:共同的规则
面向接口开发
<?php // 共同接口 // 服务端打包 interface DB { function conn(); } // 服务端开发(不知道将会被谁调用) class DbMysql implements DB { public function conn() { echo 'conn mysql <br/>'; } } class DbSqlite implements DB { public function conn() { echo 'conn sqlite <br/>'; } } // ***客户端**** (看不到DbMysql,DbSqlite的内部实现细节) // 只知道,上述两个类实现了db接口 $db = new DbMysql(); $db->conn(); $db = new DbSqlite(); $db->conn(); // 无论是开发者,还是调用者都是为接口负责
简单工厂模式
模式的作用:
发生连接的双方,知道的越少越好.
在面向对象设计法则中,重要的开闭原则: 对于修改是封闭的,对于扩展是开放的 .
<?php // 共同接口 // 服务端打包 interface DB { function conn(); } // 服务端开发(不知道将会被谁调用) class DbMysql implements DB { public function conn() { echo 'conn mysql <br/>'; } } class DbSqlite implements DB { public function conn() { echo 'conn sqlite <br/>'; } } // 简单工厂 class Factory { public static function createDB($type) { if ($type == 'mysql') { return new DbMysql(); } else if ($type == 'sqlite') { return new DbSqlite(); } else { throw new Exception('Error db type', 1); } } } // 客户端不知道服务端到底有哪些类名, // 只知道对方开放了一个Factory::createDB方法. // 静态方法允许传递数据库名称 $msqyl = Factory::createDB('mysql'); $msqyl->conn(); $sqlit = Factory::createDB('sqlite'); $sqlit->conn(); // 如果增加oracle类型,怎么办? // 服务端要修改Factory的内容(在Java,C++中,改完之后还得再编译) // 在面向对象设计法则中,重要的开闭原则 --- 对于修改是封闭的,对于扩展是开放的. // 需求可以扩展子类来实现。
工厂方法
进行扩展,避免对原有数据进行修改,只需要新增代码的子类,就可以完成。
对于修改是封闭的,对于扩展是开放的.
<?php // 共同接口 // 数据库的接口 interface DB { function conn(); } // 创造数据库的接口 interface Factory { function createDB(); } // 服务端开发(不知道将会被谁调用) class DbMysql implements DB { public function conn() { echo 'conn mysql <br/>'; } } class DbSqlite implements DB { public function conn() { echo 'conn sqlite <br/>'; } } class MySqlFactory implements Factory { public function createDB() { return new DbMysql(); } } class SqliteFactory implements Factory { public function createDB() { return new DbSqlite(); } } // ==== 服务器端添加oracle类 // 进行扩展,避免对原有数据进行修改 class orcale implements DB { public function conn() { echo 'conn orcal <br />'; } } class orcaleFactory implements Factory { public function createDB() { return new orcale(); } } // ------客户端开始调用. $fact = new MysqlFactory(); $db = $fact->createDB(); $db->conn(); $fact = new SqliteFactory(); $db = $fact->createDB(); $db->conn();
单例模式
常见使用场景:
-
需要数据库类的时候
-
操作cookie类
-
上传图片类
DB.class.php Upload.class.php Cookie.class.php // 这三个类都需要读取配置文件信息,而配置文件是共用的,因此配置读取类有一个对象就够了。 // (如何保证对象只有一个)
PHP对象什么时候全等
二个对象是一个的时候.
单例模式实现
-
封闭外部new操作
-
内部开公共接口,负责new操作,控制单一实例
-
禁止继承覆盖
__construcotr
-
防止克隆
<?php /** 单例模式 */ // 第一步,普通类 // class Single { // } // $s1 = new Single(); // $s2 = new Single(); // var_dump($s1, $s2); // var_dump($s1 == $s2); // --------------------- // 第二步,封锁new操作 // class Single { // // 在new 的时候会触发魔术函数,__constructor,可以在 __constructor 魔术函数中做操作 // protected function __constructor() { // 把__constructor()魔术方法保护起来, 导致的后果,一个对象都没法new。(大门关上了,需要开窗) // } // } // $s1 = new Single(); // --------------------- // 第三步,留接口来new对象 // class Single { // public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚 // return new self(); // 返回自身实例 // } // protected function __constructor() { // } // } // $s1 = Single::getIns(); // $s2 = Single::getIns(); // var_dump($s1, $s2); // var_dump($s1 == $s2); // --------------------- // 第四步,getIns要预先判断实例 // class Single { // protected static $ins = null; // public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚 // if (self::$ins === null) { // self::$ins = new self(); // } // return self::$ins; // 返回自身实例 // } // protected function __constructor() { // } // } // $s1 = Single::getIns(); // $s2 = Single::getIns(); // var_dump($s1, $s2); // var_dump($s1 == $s2); // true // 问题 :继承之后 constructor 被公开, 可以使用final // class multi extends Single { // public function __constructor() { // 继承之后 constructor 被公开 // } // } // --------------------- // 第五步,final,防止继承时,被修改权限 // class Single { // protected static $ins = null; // public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚 // if (self::$ins === null) { // self::$ins = new self(); // } // return self::$ins; // 返回自身实例 // } // final protected function __constructor() { // 方法前加 final,则方法不能被覆盖,类前加final,则类不能被继承。 // } // } // class multi extends Single { // public function __constructor() { // 继承之后 constructor 被公开 // } // } // $s1 = Single::getIns(); // $s2 = clone $s1; // 克隆了,又产生了多个对象. // var_dump($s1, $s2); // var_dump($s1 === $s2); // true // --------------------- // 第六步,禁止clone class Single { protected static $ins = null; public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚 if (self::$ins === null) { self::$ins = new self(); } return self::$ins; // 返回自身实例 } final protected function __constructor() { // 方法前加 final,则方法不能被覆盖,类前加final,则类不能被继承。 } // 封锁clone final protected function __clone() { } } $s1 = Single::getIns(); $s2 = clone $s1; // 克隆了,又产生了多个对象. var_dump($s1, $s2); var_dump($s1 === $s2); // true
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。