资讯专栏INFORMATION COLUMN

PHP_设计模式

Dean / 1570人阅读

摘要:责任链模式权利越大的人管理越多,越严重的问题,越得往上级找,底层的人只能管理鸡毛蒜皮的小事。使用适配器模式,转成想通模式。

什么是设计模式

在软件开发过程中,经常出现的经典场景的典型解决方案,称为设计模式

如何学习设计模式

典型场景 --> 典型问题 --> 典型解决办法

多态

用来消除逻辑语句.

多态(ploymorphism)是一个生物学上的概念,指同一特种的多种表现形态.

在面向对象中,指某种对象实例的不同表现形态.

";
  }
}

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种设计模式中,可以有些模式可以自然消除的.

面向接口开发

减少new 的操作.

熟悉概念:

调用端的概念
客户端(Client)的概念

例如:在Java中,写了一堆类,最终打成一个包。调用端可以把包引入,然后使用类中定义的方法,在开发过程中可以使用查看里面的方法。

假设:开发中引入的是sdk,都不让看。如何调用,必须开放一些接口。存在面向接口开发

接口:共同的规则

面向接口开发

";
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo "conn sqlite  
"; } } // ***客户端**** (看不到DbMysql,DbSqlite的内部实现细节) // 只知道,上述两个类实现了db接口 $db = new DbMysql(); $db->conn(); $db = new DbSqlite(); $db->conn(); // 无论是开发者,还是调用者都是为接口负责
简单工厂模式

模式的作用:
发生连接的双方,知道的越少越好.

在面向对象设计法则中,重要的开闭原则:对于修改是封闭的,对于扩展是开放的.

";
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo "conn sqlite  
"; } } // 简单工厂 class Factory { public static function createDB($type) { if ($type == "mysql") { return new DbMysql(); } else if ($type == "sqlite") { return new DbSqlite(); } else { throw new Exception("Error db type", 1); } } } // 客户端不知道服务端到底有哪些类名, // 只知道对方开放了一个Factory::createDB方法. // 静态方法允许传递数据库名称 $msqyl = Factory::createDB("mysql"); $msqyl->conn(); $sqlit = Factory::createDB("sqlite"); $sqlit->conn(); // 如果增加oracle类型,怎么办? // 服务端要修改Factory的内容(在Java,C++中,改完之后还得再编译) // 在面向对象设计法则中,重要的开闭原则 --- 对于修改是封闭的,对于扩展是开放的. // 需求可以扩展子类来实现。
工厂方法

进行扩展,避免对原有数据进行修改,只需要新增代码的子类,就可以完成。

对于修改是封闭的,对于扩展是开放的.

";
  }
}

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();
单例模式

常见使用场景:

需要数据库类的时候

操作cookie类

上传图片类

DB.class.php
Upload.class.php
Cookie.class.php
// 这三个类都需要读取配置文件信息,而配置文件是共用的,因此配置读取类有一个对象就够了。 
// (如何保证对象只有一个)

PHP对象什么时候全等

二个对象是一个的时候.

单例模式实现

封闭外部new操作

内部开公共接口,负责new操作,控制单一实例

禁止继承覆盖__construcotr

防止克隆


观察者模式

一个对象变化,引起其它对象的反应。可以让其它几个对象观察变化的对象的反应.

一对多的关系.

优点:解耦。

观察者模式中的三者: 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);

PHP实现观察者模式:

单一功能原则:类或者一个方法,完成一个功能即可.

PHP中内置接口:
Splsubject
Splobserver
内置类:
Splobjectstorage

lognum = rand(1, 10);
    $this->hobby = $hobby;
    $this->observers = new SplObjectStorage();
  }

  public function login() { // 类或者一个方法,完成一个功能即可. (单一功能原则)
    // 操作session
    $this->notify();
  }

  public function attach(SplObserver $observer) {
    $this->observers->attach($observer);
  }

  public function detach(SplObserver $observer) {
    $this->observers->detach($observer);
  }

  public function notify() {
    $this->observers->rewind();
    while($this->observers->valid()) {
      $observer = $this->observers->current();
      $observer->update($this);
      $this->observers->next();      
    }
  }
}

/**
  观察者
*/

class Secrity implements SplObserver {
  public function update(SplSubject $subject) { // 传入的 对象是$subject,$subject是干什么,随你的意.
    if($subject->lognum < 3) {
      echo "这个第" . $subject->lognum . "次安全登录
"; } else { echo "这个第" . $subject->lognum . "次登录,异常
"; } } } class Ad implements SplObserver { public function update(SplSubject $subject) { if ($subject->hobby == "sport") { echo "sport,nba
"; } else { echo "good good study, day day up
"; } } } /** Client */ $user = new User("study"); $user->attach(new Secrity()); $user->attach(new Ad()); $user->login();
职责链模式

也称之为责任链模式(chain of resionbility)

对象产生的过程中,放在逻辑判断中.
面向过程和面向对象混杂在一块,没有充分拆开。

责任链模式:

权利越大的人管理越多,越严重的问题,越得往上级找,底层的人只能管理鸡毛蒜皮的小事。

每个人都有处理事情的,权利范围.

责任链模式最终都需要都一级能够处理.

先处理最近的一级

每个对象中有职责功能,上级.
每个对象,储存着对自己上级的引用,如果自己处理不了,交给上一级。

优点:使用到那一级才会new 出那一级。

power) {
      echo "删除";
    } else {
      $top = new $this->top;
      $top->process($lev);
    }
  }
}

class admin {
  public $power = 2;
  protected $top = "police";
  public function process($lev) {
    if ($lev <= $this->power) {
      echo "封闭";
    } else {
      $top = new $this->top;
      $top->process($lev);
    }
  }
}

class police {
  protected $power;
  protected $top = null;
  public function process() {
    echo "抓!~";
  }
}

$lev = 1;

$judge = new borad(); // 距离最近的一级
$judge->process($lev);
策略模式

和工厂模式相似的一种模式

calc = new $calc();
  }

  public function calc($op1, $op2) {
    return $this->calc->calc($op1, $op2);
  }
}


$cmath = new CMath($op);
var_dump($cmath->calc(10, 100));

工厂方法和策略模式的区别:
工厂方法是传递不同参数,直接把零件(子类)进行操作。
策略模式是,真实的子类,虚拟成一个父类, 父类中操作(零件)子类。不需要直接碰子类,聚合成一个父类。

装饰器模式

问题:继承层次越来越多、

content = $content;
  }

  public function decorator() {
    return $this->content;
  }
}

$art = new Article("goods goods study, day day up 
"); echo $art->decorator(); // ----------------------------------------------------- // 文章需要, 需要编辑人员专门编辑 class BianArt extends article { // 重新加工对decorator public function summary() { return $this->content . "编辑摘要
"; } } $art = new BianArt("goods goods study, day day"); echo $art->summary(); // ----------------------------------------------------- // 文章需要, 需要做SEO class SeoArt extends BianArt { public function seo() { $content = $this->summary(); return $content . "seo
"; } } $art = new SeoArt("lz"); echo $art->seo(); // ----------------------------------------------------- // 文章需要,广告部多带带管理 class Ad extends SeoArt { // 层次越来越深,目的是:给文章添加各种内容 } // 继承层次越来越多,装饰器模式可以解决,变成俩级继承

使用装饰器模式,修改多级继承

父类负责主要逻辑,子类负责装饰,修饰。(重写父类的方法,装饰之后再次返回)

content = $content;
  }

  public function decorator() {
    return $this->content;
  }
}  

// 编辑文章
class BianArt extends BaseArt {
  
  public function __construct(BaseArt $art) {
    $this->art = $art;
    $this->decorator();
  } 

  public function decorator() {
    return $this->content = $this->art->decorator() . "编辑人员,文章摘要";
  }
}

// SEO人员
class SeoArt extends BaseArt {
  public function __construct(BaseArt $art) {
    $this->art = $art;
    $this->decorator();
  } 

  public function decorator() {
    return $this->content = $this->art->decorator() . "SEO";
  }
}


$art = new BaseArt("day day up");
// echo $art->decorator();

$art1 = new BianArt($art);
// echo $art1->decorator();

$art2 = new SeoArt($art1);
echo $art2->decorator();
适配器模式

把不适用的格式或者数据类型,转换成适用目前场景

 28, "wind" => 7, "sun" => 1);
    return serialize($today);
  }
}   


// 增加一个代理,适配器
class AdapterTainqi extends tianqi {
  public static function show() {
    $today = parent::show();
    $today = unserialize($today);
    $today = json_encode($today);
    return $today;
  }
}



// =====客户端调用=====
$taiqni = unserialize(tianqi::show());
echo "温度:",$taiqni["tep"], "风力:", $taiqni["wind"] , "
"; // java客户端,并不认识PHP的串行化后的字符串。使用适配器模式,转成想通模式。 $tq = AdapterTainqi::show(); $td = json_decode($tq); echo "温度:",$td->tep, "风力:", $td->wind;
桥接模式

在某种场景下,多个条件有共同作用,增加耦合关系,减少逻辑复杂程度
这个世界上的因素都不是单一的,都是相互耦合的.

send = $send;
  }

  abstract public function msg($content);

  public function send($to, $content) {
    $content = $this->msg($content);
    $this->send->send($to, $content);
  }
}

class zn {
  public function send($to, $content) {
    echo "zn: ", $to, "内容是:", $content;
  }
}

class email {
  public function send($to, $content) {
    echo "email: ", $to, "内容是:", $content;
  }
}

class sms {
  public function send($to, $content) {
    echo "sms: ", $to, "内容是:", $content;
  }
}


class commonInfo extends info {
  public function msg($content) {
    return "common". $content;
  }
}

class warnInfo extends info {
  public function msg($content) {
    return "warn". $content;
  }
}

class dangerInfo extends info {
  public function msg($content) {
    return "danger". $content;
  }
}


// 站内发普通信息
$commonInfo = new commonInfo(new zn());
$commonInfo->send("小明", "吃晚饭");


// sms发普通信息
$commonInfo = new commonInfo(new sms());
$commonInfo->send("小红", "吃晚饭");

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23034.html

相关文章

  • PHP设计模式(四)单例模式(Singleton)

    摘要:一什么是单例设计模式单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。 一、什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。 二、单例模式的技巧 利用$_instance私有变量来保存类的唯一实例化对象; 设计一个getInstance对外公开的函数,...

    余学文 评论0 收藏0
  • php 设计模式之工厂模式、单例模式、注册树模式

    摘要:的设计模式有很多种,本文取最简单的三种模式工厂模式单例模式和注册树模式进行简单的讲解。文件创建完后,咱们回到单元测试文件文件再执行一下单元测试命令发现,也能返回成功,这样的话我们就能很方便的修改任何驱动了。 php 设计模式之工厂模式、单例模式、注册树模式 在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具...

    liangzai_cool 评论0 收藏0
  • 单例模式的理解【php

    摘要:单例模式顾名思义,就是只有一个实例。为什么要使用单例模式语言本身的局限性语言是一种解释型的脚本语言,这种运行机制使得每个页面被解释执行后,所有的相关资源都会被回收。 单例模式(Singleton Pattern):顾名思义,就是只有一个实例。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 为什么要使用单例模式 1、PHP语言本身的局限性P...

    Invoker 评论0 收藏0
  • PHP SOAP 扩展的使用

    摘要:类也是一个只包含构造器的低级类,与和类相似。安装扩展对于平台,需要在中加入如下代码上面的工作完成之后,还需要注意的是扩展在配置文件中有独立的代码片段这些配置项主要是用来指定处理文件时使用缓存的行为。支持与扩展类似的。 原文地址:PHP SOAP 扩展,本文在原文基础上添加了一些内容和章节,也加入了一些注释,请读者注意。 前两篇文章 《SOAP 介绍》 和 《SOAP Web 服务介绍》...

    Cympros 评论0 收藏0
  • PHP_OOP

    摘要:特殊在,方法被对象调用执行时,会自动确定是那个对象调用的该方法,会使用该对象为方法内的赋值构造析构类,没有作用域,作用域,只是讲,函数内和函数外。析构在对象消失对象被销毁时,也会自动执行一个方法,称之为析构方法。 相关定义 对象(object):现实生活中的实体,在编程语言中的体现。实体都有属性和功能。一组数据,和操作管理这些数据的操作,定义在一起就形成了一个实体,称之为对象。(属性和...

    RiverLi 评论0 收藏0
  • PHP面试

    摘要:服务器返回此响应对或请求的响应时,会自动将请求者转到新位置。未授权请求要求身份验证。方法禁用禁用请求中指定的方法。请求范围不符合要求如果页面无法提供请求的范围,则服务器会返回此状态代码。服务不可用服务器目前无法使用由于超载或停机维护。 PHP基础篇 打印函数 简述一下echo print print_r var_dump区别 echo 输出一个或多个字符串,无返回值print 仅支持一...

    trilever 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<