PHP设计模式之适配器模式,建造者模式,数据访问对象模式
设计模式的目的是帮助我们以便于重用的方式来设计解决方案。
1.适配器模式Adapter
class errorObject //这个类用来存储错误信息
{
private $__error;
public function __construct($error)
{
$this->__error=$error;
}
public function getError()
{
return $this->__error;
}
}
class logToConsole
{
private $__errorObject;
public function __construct($errorObject)
{
$this->__errorObject=$errorObject;
}
public function write()
{
fwrite(STDERR,$this->__error);
}
}
调用时:
$error=new errorObject("404:Not Found");
$log=new logToConsole($error);
$log->write();
//将结果输出到控制台
这时需求变更为用不同的方式将显示错误信息在一个CSV文件中,有现成的类如下
class logToCSV
{
const CSV_LOCATION = 'log.csv';
private $__errorObject;
public function __construct($errorObject)
{
$this->__errorObject = $errorObject;
}
public function write()
{
$line=$this->__errorObject->getErrorNumber();
$line.=',';
$line=$this->__errorObject->getErrorText();
$line.="\n";
file_put_contents(self::CSV_LOCATION,$line,FILE_APPEND);
}
}
2.建造者模式Builder
class product
{
protected $_type= ' ';
protected $_size= ' ';
protected $_color= ' ';
public function setType($type)
{
$this->_type=$type;
]
public function setSize($size)
{
$this->_size=$size;
]
public function setColor($color)
{
$this->_color=$color;
}
}
在调用时:
$productConfigs=array('type'=>'shirt','size'=>'XL','color'=>'black');
$product=new product();
$product->setType($productConfigs('type'));
$product->setSize($productConfigs('size'));
$product->setColor($productConfigs('color'));
创建对象时分别调用每个方法并不是最好的做法,我们用一个建造者设计模式来创建产品实例
class productBuilder
{
protected $_product=NULL;
protected $_configs=array();
public function __construct($configs)
{
$this->_product=new product();
$this->_configs=$configs;
}
public function build()
{
$this->_product->setType($configs['type']);
$this->_product->setSize($configs['size']);
$this->_product->setColor($configs['color']);
}
public function getProduct()
{
return $this->_product;
}
}
这样build()方法隐藏了新product对象的代码实际的调用,如果以后product类发生了改变,只需要改变build方法就可以了
$builder = new productBuilder($productConfigs);
$builder = build();
$product=$builder->getProduct();
建造者设计模式的目的是消除其他对象的复杂创建过程,在某个对象的构造和配置方法改变时也可以减少重复代码的更改。
3.数据访问对象模式
数据库访问对象设计模式描述了如何创建提供透明访问任何数据源的对象。
abstruct class baseDataAccessObject
{
private $__connection;
public function __construct()
{
$this->__connectToDB(DB_USER,DB_PASS,DB_HOST,DB_DATABASE);
}
private function __connectToDB($user,$pass,$host,$database)
{
$this->__connection =mysql_connect($host,$user,$pass); //连接数据库
mysql_select_db($database,$this->_connection); //选择数据库
}
public function fetch($value,$key=NULL)
{
if(is_null($key))
$key =$this->_primaryKey;
$sql="select * from {$this->_tableName} where {$key}='{$value}' "; //sql查询语句
$results=mysql_query($sql,$this->__connection); //返回结果
$rows=array();
while($result=mysql_fetch_array($results)) //处理返回结果
{
$rows[]=$result;
}
return $rows;
}
public function update($keyedArray)
{
$sql="update {$this->_tableName} set "; //查询语句的一半
$updates =array();
foreach($keyedArray as $column=>$value)
{
$updates[]="{$column}='{$value}'";
}
$sql.=implode(',',$updates);
$sql.="where {$this->_primaryKey}='{$keyedArray[$this->_primaryKey]}'";
mysql_query($sql,$this->this->connection);
}
}
不过上面的抽象类是不能直接用的,必须继承后实例化才行
class userDataAccessObject extends baseDataAccessObject
{
protected $_tableName='userTable';
protected $_primaryKey='id';
public function getuserByFirstName($name)
{
$result=$this->fetch($name,'firstName');
return $result;
}
}
具体调用的时候:
define('DB_USER','user');
define('DB_PASS','pass');
define('DB_HOST','localhost');
define('DB_DATABASE','test');
$user=new userDataAccessObject();
$userDetailsArray =$user->fetch(1);
//获得id为1的用户信息
$updates=array('id'=>1,'firstName'=>'zxc');
$user->update($updates);
//更新id为1的用户的firstName为zxc
$userzxc=$user->getUserByFirstName('zxc');
//通过新定义的方法来从数据库中取到用户信息