PHP_设计模式

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

内容简介: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

以上所述就是小编给大家介绍的《PHP_设计模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Beginning Google Maps API 3

Beginning Google Maps API 3

Gabriel Svennerberg / Apress / 2010-07-27 / $39.99

This book is about the next generation of the Google Maps API. It will provide the reader with the skills and knowledge necessary to incorporate Google Maps v3 on web pages in both desktop and mobile ......一起来看看 《Beginning Google Maps API 3》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换