学习php设计模式 php实现享元模式(flyweight)

一、意图
运用共享技术有效的支持大量细粒度的对象
享元模式变化的是对象的存储开销
二、享元模式结构图

三、享元模式中主要角色
抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过调用商业以参数形式传入
具体享元(ConcreteFlyweight)角色:实现Flyweight接口,并为内部状态(如果有的话)拉回存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的
不共享的具体享元(UnsharedConcreteFlyweight)角色:并非所有的Flyweight子类都需要被共享。Flyweigth使共享成为可能,但它并不强制共享。
享元工厂(FlyweightFactory)角色:负责创建和管理享元角色。本角色必须保证享元对象可能被系统适当地共享
客户端(Client)角色:本角色需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外部状态
四、享元模式的优点和缺点
享元模式的优点:Flyweight模式可以大幅度地降低内存中对象的数量。
享元模式的缺点:
1、Flyweight模式使得系统更加复杂
2、Flyweigth模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长
五、享元模式适用场景
当以下情况都成立时使用Flyweight模式:
1、一个应用程序使用了大量的对象
2、完全由于使用大量的对象,造成很大的存储开销
3、对象的大多数状态都可变为外部状态
4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
5、应用程序不依赖于对象标识。
六、享元模式与其它模式
单例模式(Singleton):客户端要引用享元对象,是通过工厂对象创建或者获得的,客户端每次引用一个享元对象,都是可以通过同一个工厂对象来引用所需要的享元对象。因此,可以将享元工厂设计成单例模式,这样就可以保证客户端只引用一个工厂实例。因为所有的享元对象都是由一个工厂对象统一管理的,所以在客户端没有必要引用多个工厂对象。不管是单纯享元模式还是复合享元模式中的享元工厂角色,都可以设计成为单例模式,对于结果是不会有任何影响的。
Composite模式:复合享元模式实际上是单纯享元模式与合成模式的组合。单纯享元对象可以作为树叶对象来讲,是可以共享的,而复合享元对象可以作为树枝对象,因此在复合享元角色中可以添加聚集管理方法。
七、享元模式PHP示例

<?php
/**
 * 抽象享元角色
 */
abstract class Flyweight {

 /**
  * 示意性方法
  * @param string $state 外部状态
  */
 abstract public function operation($state);
}

/**
 * 具体享元角色
 */
class ConcreteFlyweight extends Flyweight {

 private $_intrinsicState = null;

 /**
  * 构造方法
  * @param string $state 内部状态
  */
 public function __construct($state) {
  $this->_intrinsicState = $state;
 }

 public function operation($state) {
  echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState
  . ' Extrinsic State = ' . $state . '<br />';
 }

}

/**
 * 不共享的具体享元,客户端直接调用
 */
class UnsharedConcreteFlyweight extends Flyweight {

 private $_intrinsicState = null;

 /**
  * 构造方法
  * @param string $state 内部状态
  */
 public function __construct($state) {
  $this->_intrinsicState = $state;
 }

 public function operation($state) {
  echo 'UnsharedConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState
  . ' Extrinsic State = ' . $state . '<br />';
 }

}

/**
 * 享元工厂角色
 */
class FlyweightFactory {

 private $_flyweights;

 public function __construct() {
  $this->_flyweights = array();
 }

 public function getFlyweigth($state) {
  if (isset($this->_flyweights[$state])) {
   return $this->_flyweights[$state];
  } else {
   return $this->_flyweights[$state] = new ConcreteFlyweight($state);
  }
 }

}

/**
 * 客户端
 */
class Client {

 /**
  * Main program.
  */
 public static function main() {
  $flyweightFactory = new FlyweightFactory();
  $flyweight = $flyweightFactory->getFlyweigth('state A');
  $flyweight->operation('other state A');

  $flyweight = $flyweightFactory->getFlyweigth('state B');
  $flyweight->operation('other state B');

  /* 不共享的对象,单独调用 */
  $uflyweight = new UnsharedConcreteFlyweight('state A');
  $uflyweight->operation('other state A');
 }

}

Client::main();
?>

八、复合享元模式
复合享元模式对象是由一些单纯享元使用合成模式加以复合而成
复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。
九、复合享元模式PHP示例

<?php
/**
 * 抽象享元角色
 */
abstract class Flyweight {

 /**
  * 示意性方法
  * @param string $state 外部状态
  */
 abstract public function operation($state);
}

/**
 * 具体享元角色
 */
class ConcreteFlyweight extends Flyweight {

 private $_intrinsicState = null;

 /**
  * 构造方法
  * @param string $state 内部状态
  */
 public function __construct($state) {
  $this->_intrinsicState = $state;
 }

 public function operation($state) {
  echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState
  . ' Extrinsic State = ' . $state . '<br />';
 }

}

/**
 * 不共享的具体享元,客户端直接调用
 */
class UnsharedConcreteFlyweight extends Flyweight {

 private $_flyweights;

 /**
  * 构造方法
  * @param string $state 内部状态
  */
 public function __construct() {
  $this->_flyweights = array();
 }

 public function operation($state) {
  foreach ($this->_flyweights as $flyweight) {
   $flyweight->operation($state);
  }
 }

 public function add($state, Flyweight $flyweight) {
  $this->_flyweights[$state] = $flyweight;
 }

}

/**
 * 享元工厂角色
 */
class FlyweightFactory {

 private $_flyweights;

 public function __construct() {
  $this->_flyweights = array();
 }

 public function getFlyweigth($state) {
  if (is_array($state)) { // 复合模式
   $uFlyweight = new UnsharedConcreteFlyweight();

   foreach ($state as $row) {
    $uFlyweight->add($row, $this->getFlyweigth($row));
   }
   return $uFlyweight;
  } else if (is_string($state)) {
   if (isset($this->_flyweights[$state])) {
    return $this->_flyweights[$state];
   } else {
    return $this->_flyweights[$state] = new ConcreteFlyweight($state);
   }
  } else {
   return null;
  }
 }

}

/**
 * 客户端
 */
class Client {

 /**
  * Main program.
  */
 public static function main() {
  $flyweightFactory = new FlyweightFactory();
  $flyweight = $flyweightFactory->getFlyweigth('state A');
  $flyweight->operation('other state A');

  $flyweight = $flyweightFactory->getFlyweigth('state B');
  $flyweight->operation('other state B');

  /* 复合对象*/
  $uflyweight = $flyweightFactory->getFlyweigth(array('state A', 'state B'));
  $uflyweight->operation('other state A');
 }

}

Client::main();
?>

十、PHP中享元模式的地位
相对于其它模式,Flyweight模式在PHP的现有版本中没有太大的意义,因为PHP的生命周期是页面级的,即从一个PHP文件执行开始会载入所需的资源,当执行完毕后,这些所有的资源会被全部释放,而一般来说我们也不会让一个页面执行太长时间。

以上就是使用php实现享元模式的代码,还有一些关于享元模式的概念区分,希望对大家的学习有所帮助。

(0)

相关推荐

  • php 设计模式之 工厂模式

    本人常用mysql数据库,所以程序只写了mysql的数据库操作类.希望各位高手把另外的类写全,最好能发一份给我. db_mysql.php继承db.php接口,具体实现数据库操作的各种方法 ,如果你确定你的数据库平台不会变的话不用工厂类,直接用这个就行了. 复制代码 代码如下: <?php /** * @author 黄建文 * @version V1.0 * @email hjwtp2005@qq.com * @data 2008-12-16 * =======================

  • php设计模式 Interpreter(解释器模式)

    复制代码 代码如下: <?php /** * 解释器 示例 * * @create_date: 2010-01-04 */ class Expression { function interpreter($str) { return $str; } } class ExpressionNum extends Expression { function interpreter($str) { switch($str) { case "0": return "零"

  • php设计模式 DAO(数据访问对象模式)

    复制代码 代码如下: <?php /** * 数据访问对象(Data Access Object) 示例 * * @create_date: 2010-01-04 */ class BaseDAO { var $_db = null; var $_table = null; function BaseDAO($config) { $this->_db = new MysqlDB(); // 这里的不能进行操作 } /** * 获取处理 * * @param array $filter // 过

  • php设计模式 Factory(工厂模式)

    复制代码 代码如下: <?php /** * 工厂方法模式 * * 定义一个用于创建对象的接口,让子类决定将哪一个类实例化,使用一个类的实例化延迟到其子类 */ /* class DBFactory { public static function create($type) { swtich($type) { case "Mysql": return new MysqlDB(); break; case "Postgre": return new Postg

  • 《Head First 设计模式》代码之PHP版(面向对象学习)第1/2页

    书中的例子都比较浅显易懂,不过由于是外国佬写的,所以例子的习惯不是很附合中国特色,可能偶尔看起来有些别扭,还有语言习惯也不是中国风.当然��看过这本书之后,你才能深刻理解设计模式到底能为你解决哪些问题,不能为你解决哪些问题(比如不能代替你的编码). 我将书中部分代码改成PHP,看下代码再配合概念应该是比较容易理解了. 策略模式 复制代码 代码如下: <?php /** * 策略模式 * 定义了算法族,分别封装起来,让它们之间可以互相替换, * 此模式让算法的变化独立于使用算法的客户. */ //

  • php设计模式 FlyWeight (享元模式)

    享元模式英文称为"Flyweight Pattern",我非常感谢将Flyweight Pattern翻译成享元模式的那位强人,因为这个词将这个模式使用的方式明白得表示了出来:如果翻译成为羽量级模式或者蝇量级模式等等,虽然可以含蓄的表现出使用此模式达到的目的,但是还是没有抓住此模式的关键. 享元模式的定义为:采用一个共享来避免大量拥有相同内容对象的开销.这种开销中最常见.直观的就是内存的损耗.享元模式以共享的方式高效的支持大量的细粒度对象. 在名字和定义中都体现出了共享这一个核心概念,

  • PHP最常用的2种设计模式工厂模式和单例模式介绍

    1.工厂模式 主要作用是降低耦合度. 复制代码 代码如下: abstract class Operation{ abstract public function getValue($num1,$num2); public function getAttr(){ return 1; } } class Add extends Operation{ public function getValue($num1, $num2){ return $num1+$num2; } } class Sub ex

  • 学习php设计模式 php实现享元模式(flyweight)

    一.意图 运用共享技术有效的支持大量细粒度的对象 享元模式变化的是对象的存储开销 二.享元模式结构图 三.享元模式中主要角色 抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口.那些需要外蕴状态的操作可以通过调用商业以参数形式传入 具体享元(ConcreteFlyweight)角色:实现Flyweight接口,并为内部状态(如果有的话)拉回存储空间.ConcreteFlyweight对象必须是可共享的.它所存储的状态必须是内部的 不共享的具体享元

  • Python设计模式结构型享元模式

    目录 一.享元模式 二.应用场景 三.代码示例 一.享元模式 享元,可理解为 Python 中的元类.最小粒度的类,系统中存在大量的相似对象时,可以选择享元模式提高资源利用率. 享元具有两种状态: 内蕴状态:存储在享元内部,不会随环境的改变而有所不同,是可以共享的.外蕴状态:是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的). 二.应用场景 如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式.

  • 讲解C#设计模式编程中享元模式的运用

    一.概述 在软件开发中,我们有时需要创建大量细粒度的对象,比如文档处理系统就可能需要创建成千上万的字符对象.但如果对每个字符对象都分配内存,那么在系统运行时就会耗费大量的内存.如何在保留面向对象操作方式优点的同时避免创建大量的对象呢?这就到了享元模式发挥作用的时候了. 二.享元模式 享元模式运用共享技术有效地支持大量细粒度的对象.例如可以对文档处理系统创建共享池,在共享池中建立字母和代码的对应关系,这样就可以用共享池中的26个对象解决需要创建大量对象的问题.其结构图如下: Flyweight定义

  • Python设计模式之享元模式原理与用法实例分析

    本文实例讲述了Python设计模式之享元模式原理与用法.分享给大家供大家参考,具体如下: 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式--享元模式 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象 对一个

  • Java结构型设计模式之享元模式示例详解

    目录 享元模式 概述 目的 应用场景 优缺点 主要角色 享元模式结构 内部状态和外部状态 享元模式的基本使用 创建抽象享元角色 创建具体享元角色 创建享元工厂 客户端调用 总结 享元模式实现数据库连接池 创建数据库连接池 使用数据库连接池 享元模式 概述 享元模式(Flyweight Pattern)又称为轻量级模式,是对象池的一种实现.属于结构型模式. 类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能.享元模式提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用

  • 学习JavaScript设计模式之享元模式

    一.定义 享元(flyweight)模式是一种用于性能优化的模式,核心是运用共享技术来有效支持大量细刻度的对象. 在JavaScript中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一个非常有意义的事情. 享元模式是一种用时间换空间的优化模式 内衣工厂有100种男士内衣.100中女士内衣,要求给每种内衣拍照.如果不使用享元模式则需要200个塑料模特:使用享元模式,只需要男女各1个模特. 二.什么场景下使用享元模式? (1)程序中使用大量的相似对象,造成很大的内存开销 (2)

  • C++设计模式之享元模式(Flyweight)

    享元模式顾名思义就是羽量级模式或者蝇级模式,形容体量小的应用,该模式主要的设计目的是为了迎合系统大量相似数据的应用而生,减少用于创建和操作相似的细碎对象所花费的成本.大量的对象会消耗高内存,享元模式给出了一个解决方案,即通过共享对象来减少内存负载. 作用 通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用.通过归类,将对象的属性分为内蕴状态和外蕴状态.要创建具体的享元对象,我们需要创建一个享元工厂来统一管理对象的生成和输出,享元工厂是实现享元模式的关键. 举个例子,享元

  • 23种设计模式(21)java享元模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. Java中的String类型 在JAVA语言中,String类型就是使用了享元模式.String对象是final类型,对象一旦创建就不可改变.在J

  • Java设计模式之享元模式实例详解

    本文实例讲述了Java设计模式之享元模式.分享给大家供大家参考,具体如下: 解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象.比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象.如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了.那么如果要是每个字母都共享一个对象,那么就大大节约了资源. 在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweigh

  • Java设计模式之享元模式

    本文介绍了Java设计模式之享元模式,供大家参考,具体内容如下 1.关于享元模式 享元模式有点类似于单例模式,都是只生成一个对象被共享使用.享元模式主要目的就是让多个对象实现共享,减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗. 2.享元模式结构图 因为享元模式结构比较复杂,一般结合工厂模式一起使用,在它的结构图中包含了一个享元工厂类. 在享元模式结构图中包含如下几个角色: Flyweight(抽象享元类):通常是一个接口或抽象类,

随机推荐