内容简介:PHP中常见的设计模式
什么是设计模式?
在软件开发过程中,经常出现的经典场景的典型解决方案,称为设计模式
如何学习设计模式?
典型场景 --> 典型问题 --> 典型解决办法
1.多态
-------------------------------------------------------------------------------------------------------------------------------------
用来消除逻辑语句.
多态(ploymorphism)是一个生物学上的概念,指同一特种的多种表现形态.
在面向对象中,指某种对象实例的不同表现形态.
abstract class Tiger {
public abstract function climb();
}
class XTiger extends Tiger {
public function climb() {
echo 'Drop' , '';
}
}
class MTiger extends Tiger {
public function climb() {
echo 'Up' , '';
}
}
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种 设计模式 中,可以有些模式可以自然消除的.
2.策略模式
-------------------------------------------------------------------------------------------------------------------------------------
在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 —— 一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。
//定义接口 interface IStrategy { function filter($record); } //实现接口方式1 class FindAfterStrategy implements IStrategy { private $_name; public function __construct($name) { $this->_name = $name; } public function filter($record) { return strcmp ( $this->_name, $record ) <= 0; } } //实现接口方式1 class RandomStrategy implements IStrategy { public function filter($record) { return rand ( 0, 1 ) >= 0.5; } } //主类 class UserList { private $_list = array (); public function __construct($names) { if ($names != null) { foreach ( $names as $name ) { $this->_list [] = $name; } } } public function add($name) { $this->_list [] = $name; } public function find($filter) { $recs = array (); foreach ( $this->_list as $user ) { if ($filter->filter ( $user )) $recs [] = $user; } return $recs; } } $ul = new UserList ( array ( "Andy", "Jack", "Lori", "Megan" ) ); $f1 = $ul->find ( new FindAfterStrategy ( "J" ) ); print_r ( $f1 ); $f2 = $ul->find ( new RandomStrategy () );
3.命令链模式
------------------------------------------------------------------------------------------------------------------------------------
命令链 模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。清单 5 显示了此模式的一个示例。
interface ICommand
{
function onCommand( $name, $args );
}
class CommandChain
{
private $_commands = array();
public function addCommand( $cmd )
{
$this->_commands []= $cmd;
}
public function runCommand( $name, $args )
{
foreach( $this->_commands as $cmd )
{
if ( $cmd->onCommand( $name, $args ) )
return;
}
}
}
class UserCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'addUser' ) return false;
echo( "UserCommand handling 'addUser'\n" );
return true;
}
}
class MailCommand implements ICommand
{
public function onCommand( $name, $args )
{
if ( $name != 'mail' ) return false;
echo( "MailCommand handling 'mail'\n" );
return true;
}
}
$cc = new CommandChain();
$cc->addCommand( new UserCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addUser', null );
$cc->runCommand( 'mail', null );
?>
此代码定义维护 ICommand 对象列表的 CommandChain 类。两个类都可以实现 ICommand 接口 —— 一个对邮件的请求作出响应,另一个对添加用户作出响应。
如果您运行包含某些测试代码的脚本,则会得到以下输出:
% php chain.php UserCommand handling 'addUser' MailCommand handling 'mail' %
代码首先创建 CommandChain 对象,并为它添加两个命令对象的实例。然后运行两个命令以查看谁对这些命令作出了响应。如果命令的名称匹配 UserCommand 或 MailCommand,则代码失败,不发生任何操作。
为处理请求而创建可扩展的架构时,命令链模式很有价值,使用它可以解决许多问题。
4.工厂方法
-------------------------------------------------------------------------------------------------------------------------------------
进行扩展,避免对原有数据进行修改,只需要新增代码的子类,就可以完成。
对于修改是封闭的,对于扩展是开放的.
// 共同接口
// 数据库的接口
interface DB {
function conn();
}
// 创造数据库的接口
interface Factory {
function createDB();
}
// 服务端开发(不知道将会被谁调用)
class DbMysql implements DB {
public function conn() {
echo 'conn mysql
';
}
}
class DbSqlite implements DB {
public function conn() {
echo 'conn sqlite
';
}
}
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
';
}
}
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();
5.单列模式
-------------------------------------------------------------------------------------------------------------------------------------
常见使用场景:
- 需要数据库类的时候
- 操作cookie类
- 上传图片类
DB.class.php Upload.class.php Cookie.class.php // 这三个类都需要读取配置文件信息,而配置文件是共用的,因此配置读取类有一个对象就够了。 // (如何保证对象只有一个)
PHP对象什么时候全等
二个对象是一个的时候.
单例模式实现
- 封闭外部new操作
- 内部开公共接口,负责new操作,控制单一实例
- 禁止继承覆盖__construcotr
- 防止克隆
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
6.观察者模式
-------------------------------------------------------------------------------------------------------------------------------------
一个对象变化,引起其它对象的反应。可以让其它几个对象观察变化的对象的反应.
一对多的关系.
优点:解耦。
观察者模式中的三者:Subject, Observer, Client;
// Subject attach() // 记忆多个的对象 detach() // 告知记忆的对象,变化情况 notify() // 更新通知 // Observer update() // 更新对象中执行的逻辑 // Client // 调用添加观察者`attach()`
JavaScript实现观察者模式:
var select = document.querySelector('select'); var content = document.querySelector('.content'); var ad = document.querySelector('.ad'); // Subject select.observer = {}; // 添加观察者 select.attach = function(key, obj) { this.observer[key] = obj; } // 删除观察者 select.detach = function(key) { delete this.observer[key]; } // 更新通知 select.onchange = select.ontify = function() { for (var key in this.observer) { this.observer[key].update(this); } } // Observer // 观察者 content.update = function(observer) { // 参数是被观察者对象 alert('content'); if (observer.value) { // 逻辑代码 } } ad.update = function(observer) { // 参数是被观察者对象 alert('ad'); if (observer.value) { // 逻辑代码 } } // Client // 监听 select.attach('content', content); // 只需要把独特的表示加入 对象key中 select.attach('ad', ad);
7.模版模式
-------------------------------------------------------------------------------------------------------------------------------------
模板模式准备一个抽象类,将部分逻辑以具体方法以及具体构造形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
uml类图:
角色:
抽象模板角色(MakePhone):抽象模板类,定义了一个具体的 算法 流程和一些留给子类必须实现的抽象方法。
具体子类角色(XiaoMi):实现MakePhone中的抽象方法,子类可以有自己独特的实现形式,但是执行流程受MakePhone控制。
核心:
/**
* Created by PhpStorm->
* User extends Jang
* Date extends 2015/6/10
* Time extends 11 extends 06
*/
//抽象模板类
abstract class MakePhone
{
protected $name;
public function __construct($name)
{
$this->name=$name;
}
public function MakeFlow()
{
$this->MakeBattery();
$this->MakeCamera();
$this->MakeScreen();
echo $this->name."手机生产完毕!
";
}
public abstract function MakeScreen();
public abstract function MakeBattery();
public abstract function MakeCamera();
}
//小米手机
class XiaoMi extends MakePhone
{
public function __construct($name='小米')
{
parent::__construct($name);
}
public function MakeBattery()
{
echo "小米电池生产完毕!
";
}
public function MakeCamera()
{
echo "小米相机生产完毕!
";
}
public function MakeScreen()
{
echo "小米屏幕生产完毕!
";
}
}
//魅族手机
class FlyMe extends MakePhone
{
function __construct($name='魅族')
{
parent::__construct($name);
}
public function MakeBattery()
{
echo "魅族电池生产完毕!
";
}
public function MakeCamera()
{
echo "魅族相机生产完毕!
";
}
public function MakeScreen()
{
echo "魅族屏幕生产完毕!
";
}
}
客户端测试代码;
header("Content-Type:text/html;charset=utf-8"); //-------------------------模板模式--------------------- require_once "./Template/Template.php"; $miui=new XiaoMi(); $flyMe=new FlyMe(); $miui->MakeFlow(); $flyMe->MakeFlow();
适用场景及优势:
1、完成某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时。我们通常考虑用模板模式来处理。
2、当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,我们通过模板模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
3、模板模式通过把不变的行为搬移到超级抽象类,去除子类中的重复代码来体现它的优势。模板模式提供了一个很好的代码复用平台
.....
.....
.....
.....
.....
over.....................................
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 常见设计模式要点总结
- JavaScript 常见设计模式
- 图解常见的九种设计模式
- 常见的设计模式多语言示例(C++, Java, Python, PHP, Perl)
- 常见的设计模式多语言示例(C++, Java, Python, PHP, Perl)
- 设计模式-享元设计模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C Primer Plus
Stephen Prata、云巅工作室 / 云巅工作室 / 人民邮电出版社 / 2005-2-1 / 60.00元
《C Primer Plus(第5版)(中文版)》共17章。第1、2章学习C语言编程所需的预备知识。第3到15章介绍了C语言的相关知识,包括数据类型、格式化输入输出、运算符、表达式、流程控制语句、函数、数组和指针、字符串操作、内存管理、位操作等等,知识内容都针对C99标准;另外,第10章强化了对指针的讨论,第12章引入了动态内存分配的概念,这些内容更加适合读者的需求。第16章和第17章讨论了C预处......一起来看看 《C Primer Plus》 这本书的介绍吧!