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.策略模式

-------------------------------------------------------------------------------------------------------------------------------------

 在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 —— 一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。

策略1

//定义接口

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 接口 —— 一个对邮件的请求作出响应,另一个对添加用户作出响应。 

命令链1

如果您运行包含某些测试代码的脚本,则会得到以下输出:

% 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.单列模式

-------------------------------------------------------------------------------------------------------------------------------------

常见使用场景:

  1. 需要数据库类的时候
  2. 操作cookie类
  3. 上传图片类
DB.class.php
Upload.class.php
Cookie.class.php
// 这三个类都需要读取配置文件信息,而配置文件是共用的,因此配置读取类有一个对象就够了。 
// (如何保证对象只有一个)

PHP对象什么时候全等

    二个对象是一个的时候.

单例模式实现

  1. 封闭外部new操作
  2. 内部开公共接口,负责new操作,控制单一实例
  3. 禁止继承覆盖__construcotr
  4. 防止克隆
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、模板模式通过把不变的行为搬移到超级抽象类,去除子类中的重复代码来体现它的优势。模板模式提供了一个很好的代码复用平台

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面可以对界面显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值