浅谈php设计模式
2017-05-03 15:40
645 查看
PHP一共有五个设计模式,分别对应为:
1、命令链模式
命令模式(Command)是封装一个通用操作的机制。它相当于程序中的:回调(callback)。(就是调用一个方法,方法实例化)
回调通常使用一个函数指针或数据结构如PHP中的字符串和数组实现,
[php]
view plain
copy
/**
* The Command abstraction.
* In this case the implementation must return a result,
* sometimes it only has side effects.
*/
interface Validator
{
/**
* The method could have any parameters.
* @param mixed
* @return boolean
*/
public function isValid($value);
}
/**
* ConcreteCommand.
*/
class MoreThanZeroValidator implements Validator
{
public function isValid($value)
{
return $value > 0;
}
}
/**
* ConcreteCommand.
*/
class EvenValidator implements Validator
{
public function isValid($value)
{
return $value % 2 == 0;
}
}
/**
* The Invoker. An implementation could store more than one
* Validator if needed.
*/
class ArrayProcessor
{
protected $_rule;
public function __construct (Validator $rule)
{
$this->_rule = $rule;
}
public function process(array $numbers)
{
foreach ($numbers as $n) {
if ($this->_rule->IsValid($n)) {
echo $n, "\n";
}
}
}
}
// Client code
$processor = new ArrayProcessor(new EvenValidator()); //<span style="font-family: 宋体;">new EvenValidator() 返回 </span><span style="font-family: 宋体;">EvenValidator实例化的对象 </span><span style="font-family: 宋体;">
</span>$processor->process(array(1, 20, 18, 5, 0, 31, 42));
Command是在一个方法调用之上的抽象,它吸收了所有面向对象的好处:合成、继承和处理。
2、策略模式
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
封装:把行为用接口封装起来,我们可以把那些经常变化的部分,从当前的类中单独取出来,用接口进行单独的封装。
互相替换:我们封装好了接口,通过指定不同的接口实现类进行算法的变化。
//如下
我们创建了一个超人类(duck)
还有一个基类接口类(FlyBehavior),定义了里面的一个fly()方法
建立了另外两个类FlyWithWings 和FlyWithNo 继承了FlyBehavior
类 ,FlyWithWings
和 FlyWithNo 分别重构了自己的 fly() 方法,
仿我们调用超人类(duck)时 通过调用setFlyBehavior()方法时就可以通过传不同的类,返回不同的对象.虽然他们后面调用的方法名一样.但是对象不同.
所以他们调用了不同的方法(相当于)
[php]
view plain
copy
<?php
interface FlyBehavior{
public function fly();
}
class FlyWithWings implements FlyBehavior{
public function fly(){
echo "Fly With Wings \n";
}
}
class FlyWithNo implements FlyBehavior{
public function fly(){
echo "Fly With No Wings \n";
}
}
class Duck{
private $_flyBehavior;
public function performFly(){
$this->_flyBehavior->fly();
}
public function setFlyBehavior(FlyBehavior $behavior){
$this->_flyBehavior = $behavior;//返回传的那个类
}
}
class RubberDuck extends Duck{
}
// Test Case
$duck = new RubberDuck();
/* 想让鸭子用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithWings());
$duck->performFly();
/* 想让鸭子不用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithNo());
$duck->performFly();
3、工厂模式
只要是可以根据不同的参数生成不同的类实例,那么就符合工厂模式的设计思想。
[php]
view plain
copy
<?php
//吃
class Eat(){
public static function eatNoodles(){
return '吃面';
}
}
//喝
class Drink(){
public static function drinkWater(){
return '喝水';
}
}
//吃喝拉撒
class EatAndDrink(){
public static function createObj($type){
switch($type){
case 'eat':
return new Eat();
case 'drink':
return new Drink();
}
}
}
$obj = EatAndDrink::createObj('eat');
var_dump($obj);
$obj = EatAndDrink::createObj('drink');
var_dump($obj);
?>
就如上面的代码一样,有一个单独的eat类和drink类,还有一个吃喝拉撒类,调用EatAndDrink类里面的createObj的方法来返回不同的实例化的对象
4、单元素模式(单例模式)
单元素模式(单例模式)特点:
单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,
不需要每次都去new了,这样极大的降低了资源的耗费。(如MySQL连接)
单例类至少拥有以下三种公共元素:
必须拥有一个构造函数,并且必须被标记为private。
拥有一个保存类的实例的静态成员变量。
拥有一个访问这个实例的公共的静态方法
[php]
view plain
copy
<?php
class Mysql{
//该属性用来保存实例
private static $conn;
//构造函数为private,防止创建对象
private function __construct(){
$this->conn = mysql_connect('localhost','root','');
}
//创建一个用来实例化对象的方法
public static function getInstance(){
if(!(self::$conn instanceof self)){
self::$conn = new self;
}
return self::$conn;
}
//防止对象被复制
public function __clone(){
trigger_error('Clone is not allowed !');
}
}
//只能这样取得实例,不能new 和 clone
$mysql = Mysql::getInstance();
?>
5、观察者模式
观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新!
主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点!
——针对接口编程,不针对实现编程!
[php]
view plain
copy
<?php
/**
* 观察者模式
* @author: Mac
* @date: 2012/02/22
*/
class Paper{ /* 主题 */
private $_observers = array();
public function register($sub){ /* 注册观察者 */
$this->_observers[] = $sub;
}
public function trigger(){ /* 外部统一访问 */
if(!empty($this->_observers)){
foreach($this->_observers as $observer){
$observer->update();
}
}
}
}
/**
* 观察者要实现的接口
*/
interface Observerable{
public function update();
}
class Subscriber implements Observerable{
public function update(){
echo "Callback\n";
}
}
下面是测试代码
/* 测试 */
$paper = new Paper();
$paper->register(new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper->trigger();
1、命令链模式
命令模式(Command)是封装一个通用操作的机制。它相当于程序中的:回调(callback)。(就是调用一个方法,方法实例化)
回调通常使用一个函数指针或数据结构如PHP中的字符串和数组实现,
[php]
view plain
copy
/**
* The Command abstraction.
* In this case the implementation must return a result,
* sometimes it only has side effects.
*/
interface Validator
{
/**
* The method could have any parameters.
* @param mixed
* @return boolean
*/
public function isValid($value);
}
/**
* ConcreteCommand.
*/
class MoreThanZeroValidator implements Validator
{
public function isValid($value)
{
return $value > 0;
}
}
/**
* ConcreteCommand.
*/
class EvenValidator implements Validator
{
public function isValid($value)
{
return $value % 2 == 0;
}
}
/**
* The Invoker. An implementation could store more than one
* Validator if needed.
*/
class ArrayProcessor
{
protected $_rule;
public function __construct (Validator $rule)
{
$this->_rule = $rule;
}
public function process(array $numbers)
{
foreach ($numbers as $n) {
if ($this->_rule->IsValid($n)) {
echo $n, "\n";
}
}
}
}
// Client code
$processor = new ArrayProcessor(new EvenValidator()); //<span style="font-family: 宋体;">new EvenValidator() 返回 </span><span style="font-family: 宋体;">EvenValidator实例化的对象 </span><span style="font-family: 宋体;">
</span>$processor->process(array(1, 20, 18, 5, 0, 31, 42));
Command是在一个方法调用之上的抽象,它吸收了所有面向对象的好处:合成、继承和处理。
2、策略模式
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
封装:把行为用接口封装起来,我们可以把那些经常变化的部分,从当前的类中单独取出来,用接口进行单独的封装。
互相替换:我们封装好了接口,通过指定不同的接口实现类进行算法的变化。
//如下
我们创建了一个超人类(duck)
还有一个基类接口类(FlyBehavior),定义了里面的一个fly()方法
建立了另外两个类FlyWithWings 和FlyWithNo 继承了FlyBehavior
类 ,FlyWithWings
和 FlyWithNo 分别重构了自己的 fly() 方法,
仿我们调用超人类(duck)时 通过调用setFlyBehavior()方法时就可以通过传不同的类,返回不同的对象.虽然他们后面调用的方法名一样.但是对象不同.
所以他们调用了不同的方法(相当于)
[php]
view plain
copy
<?php
interface FlyBehavior{
public function fly();
}
class FlyWithWings implements FlyBehavior{
public function fly(){
echo "Fly With Wings \n";
}
}
class FlyWithNo implements FlyBehavior{
public function fly(){
echo "Fly With No Wings \n";
}
}
class Duck{
private $_flyBehavior;
public function performFly(){
$this->_flyBehavior->fly();
}
public function setFlyBehavior(FlyBehavior $behavior){
$this->_flyBehavior = $behavior;//返回传的那个类
}
}
class RubberDuck extends Duck{
}
// Test Case
$duck = new RubberDuck();
/* 想让鸭子用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithWings());
$duck->performFly();
/* 想让鸭子不用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithNo());
$duck->performFly();
3、工厂模式
只要是可以根据不同的参数生成不同的类实例,那么就符合工厂模式的设计思想。
[php]
view plain
copy
<?php
//吃
class Eat(){
public static function eatNoodles(){
return '吃面';
}
}
//喝
class Drink(){
public static function drinkWater(){
return '喝水';
}
}
//吃喝拉撒
class EatAndDrink(){
public static function createObj($type){
switch($type){
case 'eat':
return new Eat();
case 'drink':
return new Drink();
}
}
}
$obj = EatAndDrink::createObj('eat');
var_dump($obj);
$obj = EatAndDrink::createObj('drink');
var_dump($obj);
?>
就如上面的代码一样,有一个单独的eat类和drink类,还有一个吃喝拉撒类,调用EatAndDrink类里面的createObj的方法来返回不同的实例化的对象
4、单元素模式(单例模式)
单元素模式(单例模式)特点:
单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,
不需要每次都去new了,这样极大的降低了资源的耗费。(如MySQL连接)
单例类至少拥有以下三种公共元素:
必须拥有一个构造函数,并且必须被标记为private。
拥有一个保存类的实例的静态成员变量。
拥有一个访问这个实例的公共的静态方法
[php]
view plain
copy
<?php
class Mysql{
//该属性用来保存实例
private static $conn;
//构造函数为private,防止创建对象
private function __construct(){
$this->conn = mysql_connect('localhost','root','');
}
//创建一个用来实例化对象的方法
public static function getInstance(){
if(!(self::$conn instanceof self)){
self::$conn = new self;
}
return self::$conn;
}
//防止对象被复制
public function __clone(){
trigger_error('Clone is not allowed !');
}
}
//只能这样取得实例,不能new 和 clone
$mysql = Mysql::getInstance();
?>
5、观察者模式
观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新!
主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点!
——针对接口编程,不针对实现编程!
[php]
view plain
copy
<?php
/**
* 观察者模式
* @author: Mac
* @date: 2012/02/22
*/
class Paper{ /* 主题 */
private $_observers = array();
public function register($sub){ /* 注册观察者 */
$this->_observers[] = $sub;
}
public function trigger(){ /* 外部统一访问 */
if(!empty($this->_observers)){
foreach($this->_observers as $observer){
$observer->update();
}
}
}
}
/**
* 观察者要实现的接口
*/
interface Observerable{
public function update();
}
class Subscriber implements Observerable{
public function update(){
echo "Callback\n";
}
}
下面是测试代码
/* 测试 */
$paper = new Paper();
$paper->register(new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper->trigger();
相关文章推荐
- 结合PHP -----浅谈设计模式之单件模式
- 浅谈php之设计模式基础
- 浅谈php设计模式(1)---工厂模式
- 浅谈php设计模式之责任链模式
- 五种常见的PHP设计模式
- 浅谈PHP开发中的MVC单点入口模式
- 五种常见的PHP设计模式(择自互联网非本人所写)
- 五种常见的PHP设计模式
- [转]五种常见的PHP设计模式
- php设计模式介绍之编程惯用法第1/3页
- 浅谈设计模式
- 架构师常用的五种 PHP 设计模式
- php设计模式介绍之值对象模式第1/5页
- [转]五种常见的PHP设计模式
- [介绍]PHP设计模式:DAO(数据访问对象模式)
- 设计模式浅谈
- 五种常见的PHP设计模式
- [介绍]PHP设计模式:DAO(数据访问对象模式)
- php设计模式-中级
- 一种PHP设计模式:DPT