PHP_设计模式

栏目: PHP · 发布时间: 7年前

内容简介:PHP_设计模式

什么是设计模式

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

如何学习设计模式

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

多态

用来消除逻辑语句.

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

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

<?php

abstract class Tiger {
  public abstract function climb();
}

class XTiger extends Tiger {
  public function climb() {
    echo 'Drop' , '<br/>';
  }
}

class MTiger extends Tiger {
  public function climb() {
    echo 'Up' , '<br/>';
  }
}

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 ,都不让看。如何调用,必须开放一些接口。存在 面向接口开发

接口:共同的规则

面向接口开发

<?php


// 共同接口
// 服务端打包
interface DB {
  function conn();
}


// 服务端开发(不知道将会被谁调用)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


// ***客户端**** (看不到DbMysql,DbSqlite的内部实现细节)
// 只知道,上述两个类实现了db接口

$db = new DbMysql();
$db->conn();

$db = new DbSqlite();
$db->conn();

// 无论是开发者,还是调用者都是为接口负责

简单工厂模式

模式的作用:

发生连接的双方,知道的越少越好.

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

<?php


// 共同接口
// 服务端打包
interface DB {
  function conn();
}


// 服务端开发(不知道将会被谁调用)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


// 简单工厂
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++中,改完之后还得再编译)
// 在面向对象设计法则中,重要的开闭原则 --- 对于修改是封闭的,对于扩展是开放的.

// 需求可以扩展子类来实现。

工厂方法

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

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

<?php


// 共同接口
// 数据库的接口
interface DB {
  function conn();
}

// 创造数据库的接口
interface Factory {
  function createDB();
}

// 服务端开发(不知道将会被谁调用)
class DbMysql implements DB {
  public function conn() {
    echo 'conn mysql <br/>';
  }
}

class DbSqlite implements DB {
  public function conn() {
    echo 'conn sqlite  <br/>';
  }
}


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 <br />';
  }
}

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();

单例模式

常见使用场景:

  1. 需要数据库类的时候

  2. 操作cookie类

  3. 上传图片类

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

PHP对象什么时候全等

二个对象是一个的时候.

单例模式实现

  1. 封闭外部new操作

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

  3. 禁止继承覆盖 __construcotr

  4. 防止克隆

<?php

/**
  单例模式
*/

// 第一步,普通类

// class Single {

// }


// $s1 = new Single();
// $s2 = new Single();

// var_dump($s1, $s2);
// var_dump($s1 == $s2);

// ---------------------

// 第二步,封锁new操作
// class Single {
//   // 在new 的时候会触发魔术函数,__constructor,可以在 __constructor 魔术函数中做操作 
//   protected function __constructor() { // 把__constructor()魔术方法保护起来, 导致的后果,一个对象都没法new。(大门关上了,需要开窗)

//   }
// }

// $s1 = new Single();


// ---------------------

// 第三步,留接口来new对象
// class Single {
//    public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚
//      return new self(); // 返回自身实例
//    } 
//    protected function __constructor() {

//    }
// }

// $s1 = Single::getIns();
// $s2 = Single::getIns();

// var_dump($s1, $s2);
// var_dump($s1 == $s2);



// ---------------------

// 第四步,getIns要预先判断实例
// class Single {
//    protected static $ins = null;
//    public static function getIns() { // getIns的控制权在class内部,可以在getIns做手脚
//      if (self::$ins === null) {
//        self::$ins = new self();
//      }
//      return self::$ins;  // 返回自身实例
//    } 
//    protected function __constructor() {

//    }
// }

// $s1 = Single::getIns();
// $s2 = Single::getIns();

// var_dump($s1, $s2);
// var_dump($s1 == $s2); // true

// 问题 :继承之后 constructor 被公开, 可以使用final
// class multi extends Single {
//   public function __constructor() { // 继承之后 constructor 被公开

//   }
// } 




// ---------------------

// 第五步,final,防止继承时,被修改权限
// 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,则类不能被继承。

//    }
// }

// class multi extends Single {
//   public function __constructor() { // 继承之后 constructor 被公开

//   }
// } 

// $s1 = Single::getIns();
// $s2 = clone $s1; // 克隆了,又产生了多个对象.

// var_dump($s1, $s2);
// var_dump($s1 === $s2); // true




// ---------------------

// 第六步,禁止clone
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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

浪潮之巅

浪潮之巅

吴军 / 电子工业出版社 / 2011-8 / 55.00元

近一百多年来,总有一些公司很幸运地、有意识或无意识地站在技术革命的浪尖之上。在这十几年间,它们代表着科技的浪潮,直到下一波浪潮的来临。 从一百年前算起,AT&T 公司、IBM 公司、苹果公司、英特尔公司、微软公司、思科公司、雅虎公司和Google公司都先后被幸运地推到了浪尖。虽然,它们来自不同的领域,中间有些已经衰落或正在衰落,但是它们都极度辉煌过。本书系统地介绍了这些公司成功的本质原因及科......一起来看看 《浪潮之巅》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码