《一天一个设计模式》整理转载

Standard

<<一天一个设计模式>>
转自phpchina论坛 作者ID:kakashilw

一、工厂模式
1、先看一个简单的例子

<?php
interface IUser
{
  function getName();
}
class User implements IUser
{
  public static function Load( $id ) 
  {
        return new User( $id );
  }
  public static function Create( ) 
  {
        return new User( null );
  }
  public function __construct( $id ) { }
  public function getName()
  {
    return "Jack";
  }
}
$uo = User::Load( 1 );
echo( $uo->getName()."n" );
?>

2、一个稍微复杂但却相当经典的例子

<?php
//BT种子的接口
interface BT
{
    public function process();
}
//BT种子的下载处理类
class BTdown implements BT
{
    public function process()
    {
        //输出BT种子
        echo '输出BT种子';
    }
}
//BT种子的上传处理类
class BtUpload implements BT
{
    public function process()
    {
        //保存上传的BT种子
        echo '保存上传的BT种子';
    }
}
---------------------------------------------------------------
//生产BT种子处理对象的设备的接口
interface BTcreator
{
    public function createBTObject();
}
//生产BT种子下载处理对象的设备
class BTdownCreator implements BTcreator
{
    public function createBTObject()
    {
        /**
        * 如果不是管理员,送10点积分
        */
        //然后返回BT种子下载处理对象
        return new BTdown();
    }
}
//生产BT种子上传处理对象的设备
class BTUploadCreator implements BTcreator
{
    public function createBTObject()
    {
    /**
    * 如果不是管理员,扣10点积分
    */
    //然后返回BT种子下载处理对象
    return new BtUpload();
    }
}
------------------------------------------------------------------
//生产BT种子处理对象的工厂
class BtFactory
{
    //获取电影处理类的对象,参数为类名
    public function getBtObject($name)
    {
        switch ($name) {
        case 'BTdown':
        $creator = new BTdownCreator();
        break;
        case 'BtUpload':
        $creator = new BtUploadCreator();
        break;
    }
    return $creator->createBTObject();
}
}
---------------------------------------------------------------------
//获取bt工厂
$btFactory = new BtFactory();
//BT种子的下载处理
$what = 'BTdown';
$btObject = $btFactory->getBtObject($what);
$btObject->process();
//BT种子的上传处理
$what = 'BtUpload';
$btObject = $btFactory->getBtObject($what);
$btObject->process();
?>

二、单件模式

<?php
class userInfo
{
    private $userName;
    //唯一的实例
    private static $instance;
    //构造方法
    private function __construct()
    {
        //查询数据库,获得用户名
        $this->userName = 'lightsaber';
    }
    //获取对象实例
    public static function getInstance()
    {
        if (self::$instance=='') self::$instance = new userInfo();
        return self::$instance;
    }
    //返回用户信息
    public function getUserInfo()
    {
        return $this->userName;
    }
}
//获取唯一的实例
$userInfo = userInfo::getInstance();
//显示用户名
echo '用户名是'.$userInfo->getUserInfo().'<br>';
//天气播报
echo '向用户'.$userInfo->getUserInfo().'播报天气<br>';
?>

其实单件模式还是比较好理解的一个模式,比如上面这个例子,用在数据库链接上,就可以保证数据库的唯一连接了。
而单件模式也可以用于减少数据库的查询,感觉这个作用也是大大地~~~~,如下:

<?php
class userInfo
{
    private static $userName;
    //查询数据库,获得用户名
    private static function findUserInfo()
    {
        //查询数据库,获得用户名
        self::$userName = 'lightsaber';
    }
    public static function getUserInfo()
    {
        //判断是否已经获取了用户数据
        if (self::$userName=='') self::findUserInfo();
        return self::$userName;
    }
}
//显示用户名
echo '用户名是'.userInfo::getUserInfo().'<br>';
//天气播报
echo '向用户'.userInfo::getUserInfo().'播报天气<br>';
?>

三、备忘模式
今天学的是备忘模式,简单理解比喻下就是类似平时我们用的word”撤销”,”恢复”…
1.UNDO

<?php
//备忘类
class Memento
{
    public function backup()
    {
        //保存现有的分页样式
        echo '样式已经保存<br>';
    }
    public function restore()
    {
        //用保存的样式去覆盖
        echo '样式已经恢复<br>';
    }
}
----------------------------------------------------
//设置分页样式
class ListStyle
{
    //备忘对象
    private $memento;
 
    //构造方法
    public function __construct()
    {
        $this->memento = new Memento();
    }
    //设置样式
    public function setStyle()
    {
        //开始先备份样式
        $this->memento->backup();
        //设置样式
        echo '设置了样式<br>';
    }
    //撤销方法
     public function undo()
    {
        $this->memento->restore();
    }
}
----------------------------------------------------
$listStyle = new ListStyle();
//设置样式,同时备份
$listStyle->setStyle();
//撤销设置
$listStyle->undo();
?>

2.REDO

<?php
//备忘类
class Memento
{
    public function backup()
    {
        //保存现有的分页样式
        echo '样式已经保存<br>';
    }
 
    public function restore()
    {
        //用保存的样式去覆盖
        echo '样式已经恢复<br>';
    }
}
//设置分页样式
class ListStyle
{
    //备忘对象
    private $memento;
 
    //构造方法
    public function __construct()
    {
        $this->memento = new Memento();
    }
    //设置样式
    public function setStyle()
    {
        //开始先备份样式
        $this->memento->backup();
 
        //设置样式
        echo '设置了样式<br>';
    }
    //撤销方法
     public function undo()
    {
        //先保存,为了redo
        $this->memento->backup();
        $this->memento->restore();
    }
    //重做方法
    public function redo()
    {
        $this->memento->restore();
    }
}
$listStyle = new ListStyle();
//设置样式,同时备份
$listStyle->setStyle();
//撤销设置
$listStyle->undo();
//重做设置
$listStyle->redo();
?>

简单总结下,就是有相应的一个类,来做backup和restore用的…

四、策略模式
策略模式(Strategy),将不同情况的算法分拆到不同的类(比如advanceDiscountor类),然后调用者(discountor类)根据具体的情况,用算法类的对象来处理。

<? php
//打折接口
interface IDiscountor
{
    public function getDiscount();
}
------------------------------------------------------------------------------------
//普通用户打折类
class commonDiscountor implements IDiscountor 
{
    public function getDiscount()
    {
        $discount = 1;
        return $discount;
    }
}
//高级用户打折类
class advanceDiscountor implements IDiscountor 
{
    public function getDiscount()
    {
        $discount = 0.9;
        return $discount;
    }
}
//vip用户打折类
class vipDiscountor implements IDiscountor 
{
    public function getDiscount()
    {
        $discount = 0.8;
        return $discount;
    }
}
----------------------------------------------------------------------------------
//打折类
class discountor
{
    public function getDiscount($rank)
    {
        switch ($rank) {
        case 'common':
            $discountor = new commonDiscountor();
            break;
        case 'advance':
            $discountor = new advanceDiscountor();
            break;
        case 'vip':
            $discountor = new vipDiscountor();
            break;
        }
        return $discountor->getDiscount();
    }
} 
$discountor = new discountor();
echo $discountor->getDiscount('advance');
?>

五、状态模式

<?php
//积分基础类
class Point
{
    //积分
    public $point;
 
    public function showPoint()
    {
        //列出用户的积分
    }
    public function showUseRecord()
    {
        //列出用户的积分使用记录
    }
}
--------------------------------------------------------------------------
//积分低于500的类
class Point500 extends Point
{
    //显示提示
    public function showTips()
    {
            echo "客户发帖等行为可以增加积分";
    }
    //显示按钮
    public function showButton()
    {
            echo "";
    }
}
//积分大于500,低于1000的类
class Point600 extends Point
{
    //显示提示
    public function showTips()
    {
            echo "可以行使标准用户的权利";
    }
    //显示按钮
    public function showButton()
    {
            echo "标准用户功能的按钮";
    }
}
//积分大于1000的类
class Point1000 extends Point
{
    //显示提示
    public function showTips()
    {
            echo "可以行使高级用户的权利";
    }
    //显示按钮
    public function showButton()
    {
            echo "高级用户的按钮";
    }
}
--------------------------------------------------------------------------
//应用环境类,简单的理解为调用环境就可以了
class Context
{
    //积分对象
    public $pointObj;
 
    //设置一个积分对象
    public function setPointObj($point)
    {
        //低于500
        if ($point<500) {
            $this->pointObj = new Point500();
        }
        //大于1000
        elseif ($point>1000) {
            $this->pointObj = new Point1000();
        }
        //大于500,低于1000
        else {
            $this->pointObj = new Point600();
        }
    }
    public function showPoint()
    {
        $this->pointObj->showPoint();
    }
    public function showUseRecord()
    {
        $this->pointObj->showUseRecord();
    }
    //显示提示
    public function showTips()
    {
       $this->pointObj->showTips();
    }
    //显示按钮
    public function showButton()
    {
        $this->pointObj->showButton();
    }
}
--------------------------------------------------------------------------
$context = new Context();
$context->setPointObj(780);
//显示提示
$context->showTips();
?>

优点:更好的阅读,扩展,已经封装

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.