PHP_设计模式

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

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

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

查看所有标签

猜你喜欢:

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

The Everything Store

The Everything Store

Brad Stone / Little, Brown and Company / 2013-10-22 / USD 28.00

The definitive story of Amazon.com, one of the most successful companies in the world, and of its driven, brilliant founder, Jeff Bezos. Amazon.com started off delivering books through the mail. Bu......一起来看看 《The Everything Store》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具