php 设计模式系列(一)

时间:2021-02-24 23:13:59

参考文章:http://duchengjiu.iteye.com/blog/2227452

多态代码

// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法

// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法
abstract class Tiger {
public abstract function climb();
} class XTiger extends Tiger {
public function climb() {
echo '摔下来';
}
} class MTiger extends Tiger {
public function climb() {
echo '爬到树顶';
}
} class Client {
public static function call(Tiger $animal) {
$animal->climb();
}
} Client::call(new XTiger());
Client::call(new MTiger());

  

面向接口开发代码

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
interface db {
function conn();
} // 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
public function conn() {
echo '连上了MySQL';
}
} class dbsqlite implements db{
public function conn() {
echo '连上了sqlite';
}
} // 客户端, 看不到dbmysql, dbsqlite的内部细节的, 只知道上两个类实现了db接口. $db = new dbmysql();
$db->conn(); // 因为知道这个类实现了db接口, 所以知道有这个conn类 $sqlite = new dbsqlite();
$sqlite->conn(); // 我连我有哪些类我都不希望告诉客户端, 那么怎么进一步进行封装
// 发生连接的双方知道的越少越好, 你还知道我有两个类

  简单工厂模式代码

// 简单工厂

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
interface db {
function conn();
} // 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
public function conn() {
echo '连上了MySQL';
}
} class dbsqlite implements db{
public function conn() {
echo '连上了sqlite';
}
} // 简单工厂
class Factory {
public static function createDB($type) {
if($type == 'mysql') {
return new dbmysql();
} elseif ($type=='sqlite') {
return new dbsqlite();
} else {
throw new Exception("Error db type", 1);
}
}
} // 客户端现在不知道对方到底有哪些类名了
// 只知道对方开放了一个Factory::createDB方法
// 方法允许传递数据库名称 $mysql = Factory::createDB('mysql');
$mysql->conn(); $sqlite = Factory::createDB('sqlite');
$sqlite->conn(); // 原本你知道服务器端的两个类名, 觉得你知道的太多, 再封装起来, 只给一个通道, 更好的适应变化
// 如果以后新增oracle类型, 怎么办?
// 我们PHP随手改了就行, 像JAVA打包一次很麻烦, 又要修改服务端内容
// 服务端要修改Factory的内容(在java, c++中, 改后还得再编译)
// 这个时候就想如何来改进呢
// 在OOD(面向对象设计)的法则中, 有重要的开闭原则--对于修改是封闭的, 对于扩展是开放的.
// 你可以新增一个源代码, 不要修改旧的代码 //现在用第二种办法, 叫工厂方法

  工厂方法代码

// 共同接口
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 mysqliFactory implements Factory{
public function createDB() {
return new dbmysql();
}
} class sqliteFactory implements Factory {
public function createDB() {
return new dbsqlite();
}
} // 服务器端添加oracle类
// 前面的代码不用改
// 我就新增一个数据库驱动类和一个工厂, 这样就避免了对源代码的修改
class dboracle implements db {
public function conn() {
echo '连接上了oracle';
}
} class oracleFactory implements Factory {
public function createDB() {
return new dboracle();
}
} // 客户端开始, 对方给了两个api, 一个db的api, 一个是创造数据库的api
$fact = new mysqliFactory();
$db = $fact->createDB();
$db->conn(); $fact = new sqliteFactory();
$db = $fact->createDB();
$db->conn();

  单例设计模式代码

// 单例
// 一般来说一个中小型网站一个db去连接数据库就行了
// 想想, 能不能只有一个db类, 一个upload类, 一个cookie类
// 类肯定只有一个, 如何保证类的实例也只有一个 // 2个对象是同一个的时候才全等 // 单例模式 class single {
protected static $ins = null; // 控制权限, *new操作, 把大门关上了, 需要留一个小窗户
// 方法前加final, 则方法不能被覆盖, 类前加final, 则类不能被继承
final protected function __construct() {}
// 防clone
final protected function __clone(){} //留一个接口来new对象
public static function getIns() {
if(self::$ins == null) {
self::$ins = new self();
}
return self::$ins;
}
} $s1 = single::getIns();
$s2 = single::getIns(); if ($s1 === $s2) {
echo '是一个对象';
} else {
echo '不是一个对象';
}