注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Copper peas ' Bolg

Keep On Moving...This Is My Life...

 
 
 

日志

 
 

【原】 PHP 设计模式十九之享元设计模式  

2011-06-23 16:22:56|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

<?php
/**
 * 点菜 享元设计模式(单纯享元模式)
 * 定义:享元模式以共享的方式高效的支持大量的细粒度对象。采用一个共享来避免大量拥有相同内容对象的开销
 * 享元模式可以分为单纯享元模式和复杂享元模式,后者可以认为是前者是组合。
 * @anthor Chen Wei Han <csq-3@163.com>
 * @copyright Chen Wei Han 2011-6-23上午09:54:38
 * @link http://csq-3.blog.163.com
 * @package demo
 * @version 1.0
 * 写该例子花费了我大半天时间,主要是很多例子不恰当,误导人,还有就是网上很例子都只体现了对象中的共享的处理没有体现对象差异的处理
 * 网上一篇C#的点菜案例,我看了一上午实在看不懂他写的意思,估计我理解能力有限。
 * 现在我整理一下我的思路,按照我自己的思路写了下面的代码
 */

/**
 * 案例说明:一盘菜和点菜人的关系
 * 这里有点与实际生活不同,需要一个假设:点过的菜就不需要重新做了,直接可以端出。
 * 一盘菜作对象: 属性:1:菜名(相同)内蕴   2:点菜人(不相同)(外蕴)
 * $list数组保存已点菜对象[菜名=>对应菜的对象]
 *
 * 有点按需载入对象,然后在载入对象里面在优化的感觉。一切都是以节约资源为主
 */

/**
 * 抽象享元类 里面抽象方法根据实际情况而定
 */
header("Content-type:text/html;charset=uft-8");
abstract class abstract_flyweight
{
    protected $caiperson;
 
 public function setperson($person)
 {
  $this->caiperson = $person;
 }
 
 //显示菜
 abstract public function display();
 
}

/**
 * 享元对象 土豆丝菜对象共享,不同的属性从外部引入
 * [菜名或者有其他共性的父类,PHP不支持多继承,这里可以灵活使用接口的多继承结合抽象类来使用
 * extends abstract_flyweight  implements caiming]
 */
class tudousi extends abstract_flyweight
{
 private $cainame;
   
 public function __construct()
 {
  $this->cainame = "土豆丝!";
 }
  
 public function display()
 {
  echo $this->caiperson.$this->cainame."</br>";
 }
}

/**
 * 享元工厂
 */
class FlyweightFactoy
{
 /**
  * 存储实例化的对象
  */
 private $list=array();
 
 /**
  * 菜对象
  */ 
 private $caiobj;
 
 /**
  * 单例保存变量
  */
 private static $_instance;
 
 /**
  * 菜谱
  */ 
 private $caipu;
 
 /**
  * 单例模式 (关键是这个数组需要共享,就只能调用相同的对象才能保证,只能单例)
  */
 private function __construct(){}
 public static function getInstance()
 {
      if(!(self::$_instance instanceof self))
      {           
       self::$_instance = new self();      
      }       
      return self::$_instance;
  }
 
  public function setcaipu($caipu)
  {
      $this->caipu = $caipu;
  }
   
 /**
  * 工厂实例类
  */
 public function fwfactoy($person,$cainame)
 {
  
   if(array_key_exists($cainame,$this->caipu))
         { 
  
    if(array_key_exists($this->caipu[$cainame],$this->list))
    {    
     echo "使用已创建类".$cainame."</br>";
     $this->caiobj =$this->list[$this->caipu[$cainame]];
    }
    else
    {               
                    $this->caiobj  = new $this->caipu[$cainame];
                    echo "创建类".$cainame."</br>";
           //新菜做好保存的工作,方便下次调用     
           $this->list[$this->caipu[$cainame]]= $this->caiobj;
               }         
      //上菜 取出菜,加工下,标识好点菜人
         $this->caiobj->setperson($person);
         return $this->caiobj;  
   } 
   else
         {
               throw new Exception("我们店没有这道菜!");
         }
  
 }
}

//菜谱上的菜 [这里主要是解决汉语名称与类名名称的映射,也降低耦合,以免修改菜名映射修改类]

$caipu=array(
   "土豆丝"=>"tudousi"
);


$fwf = FlyweightFactoy::getInstance();

//载入菜谱
$fwf ->setcaipu($caipu);

//张三土豆丝
$zscai=$fwf->fwfactoy('张三','土豆丝');
$zscai->display();

//李四土豆丝
$lscai=$fwf->fwfactoy('李四','土豆丝');
$lscai->display();

//王麻子土豆丝
$lscai=$fwf->fwfactoy('王麻子','土豆丝');
$lscai->display();

 

 

/**
      享元模式可以避免大量非常相似类的开销。在程序设计中有时需要生成大量细粒度的类实例来表示数据。如果发现这些实例除了几个参数外基本伤都是相同的,有时就能够受大幅度第减少需要实例化的类的数量。如果能把这些参数移到类实例外面,在方法调用时将他们传递进来,就可以通过共享大幅度地减少单个实例的数目。
  享元对象的内部状态与外部状态:
  内部状态,在享元对象的内部并且不会随环境改变而改变的共享部分。
  外部状态,随环境改变而改变的,不可以共享的状态。
 */

  评论这张
 
阅读(123)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018