设计模式篇
什么是设计模式?
在软件开发过程中,经常出现的典型场景的典型解决方案,称为设计模式,生活中也有很多设计模式,例如泡妞技术,下象棋中当头炮马一跳等等固定章法等等。学会了设计模式可以帮助我们了解框架底层代码的实现也可以提高我们的编程水平。
一、说说多态
在正式了解设计模式前需要聊聊多态,多态字面上理解,同一物种表现出的多种心态,在面向对象中某种对象的实例的不同表现形态
代码如下(示例):
<?php
/**
* @desc 定义一个抽象类Tiger
*/
abstract class Tiger{
public abstract function climb();
}
/**
* @desc 定义XTiger继承抽象类Tiger
*/
class XTiger extends Tiger{
public function climb()
{
echo "bottoms\r\n";
}
}
/**
* @desc 定义MTiger继承抽象类Tiger
*/
class MTiger extends Tiger{
public function climb()
{
echo "tops\r\n";
}
}
/**
* @desc 声明类Cat
*/
class Cat{
public function climb()
{
echo 'middle';
}
}
/**
* @desc 声明一个clients类,再定一个call方法
*/
class Clients{
public function call(Tiger $animal)
{
$animal->climb();
}
}
$client = new Clients();
$client->call(new XTiger());
$client->call(new MTiger());
$client->call(new Cat());
?>
二、面向接口开发
查看代码注释,理解接口的实现,或者可以把代码复制实际运行下
代码如下(示例):
<?php
/**
* @author 面向接口发开, 服务端和客户端共同为接口开发
*/
interface db{
/**
* @desc 共同接口
*/
function conn();
}
/**
* @desc 定义dbmysql类继承接口db
*/
class dbmysql implements db{
public function conn()
{
echo ' mysql done';
}
}
/**
* @desc 定义dbsqlite类继承接口db
*/
class dbsqlite implements db{
public function conn()
{
echo 'sqlite done';
}
}
$db = new dbmysql();
$db->conn();
$db = new dbsqlite();
$db->conn();
?>
三、简单工厂类
<?php
interface db{
function conn();
}
class dbmysql implements db{
public function conn()
{
echo ' mysql done';
}
}
class dbsqlite implements db{
public function conn()
{
echo 'sqlite done';
}
}
//简单工厂,使用该模式只对客户提供一个createDB方法即可
class Factorys{
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 = Factorys::createDB('mysql');
$mysql->conn();
$sqllite = Factorys::createDB('sqlite');
$sqllite->conn();
实现了客户端不知道服务器端到底有哪些类名,只知道对方开放了一个Factory::createDB方法只允许传递数据库名称,如果我们要新增一个oracle连接类,怎么办?在php中服务端要修改Factorys的内容可以实现,但这违背了面向对象设计中一条很重要的原则:对于类的修改是封闭的,对于扩展是开放的,如果是java或c++强类型语言修改factorys类还得重新编译,因此会显得很麻烦,接着往下阅读解决这一问题。
四、工厂方法
<?php
/**
* @desc 定义db接口类
*/
interface db{
function conn();
}
/**
* @desc 定义Factory接口
*/
interface Factory{
function createDB();
}
class dbmysql implements db{
public function conn()
{
echo ' mysql done';
}
}
class dbsqlite implements db{
public function conn()
{
echo 'sqlite done';
}
}
class mysqlFactory implements Factory{
public function createDB(){
return new dbmysql();
}
}
class sqliteFactory implements Factory{
public function createDB(){
return new dbsqlite();
}
}
$factory = new mysqlFactory();
$db = $factory->createDB();
$db->conn();
$factory = new sqliteFactory();
$db = $factory->createDB();
$db->conn();
//如果要新增oracle连接的实现案例
//服务器端添加dboracle类
//前面代码不用改
class dboracle implements db{
public function conn(){
echo 'oracle connected';
}
}
class oracleFactory implements Factory{
public function createDB(){
return new dboracle();
}
}
$factory = new oracleFactory();
$db = $factory->createDB();
$db->conn();
上面示例中通过新增dboracle类和oracleFactory工厂类实现了新增oracle数据库连接的方法,也尊守了面向对象设计中对于修该是封闭的,对于扩展是开放的,若是java或c++程序只需要发布一个包上传服务器即可,无须全量打包,对于php只需要新增文件的方法解决这一问题。
总结
这一节介绍了基础概念多态和面向接口开发,在简单工厂类示例中使用了Factory::createDB(‘mysql’)连接mysql和Factorys::createDB(‘sqlite’)连接sqlite功能。如果需要新增oracle连接类,怎么办?接下来引入了工厂方法解决这一问题,在面向对象程序设计中有一条重要的开闭原则–对于修改是封闭的,对于扩展是开放的。