月度归档:2010年08月

PHP设计模式笔记:使用PHP实现合成模式

PHP设计模式笔记:使用PHP实现合成模式

【意图】
将对象组合成树形结构以表示”部分-整体”的层次结构。Composite使用户对单个对象和组合对象的使用具有一致性。
Composite变化的是一个对象的结构和组成

【合成模式中主要角色】
抽象组件(Component)角色:抽象角色,给参加组合的对象规定一个接口。在适当的情况下,实现所有类共有接口的缺省行为。声明一个接口用于访问和管理Component的子组件
树叶组件(Leaf)角色:在组合中表示叶节点对象,叶节点没有子节点。在组合中定义图元对象的行为。
树枝组件(Composite)角色:存储子部件。定义有子部件的那些部件的行为。在Component接口中实现与子部件有关的操作。
客户端(Client):通过Component接口操纵组合部件的对象

【合成模式的优点和缺点】
Composite模式的优点
1、简化客户代码
2、使得更容易增加新类型的组件

Composite模式的缺点:使你的设计变得更加一般化,容易增加组件也会产生一些问题,那就是很难限制组合中的组件

【合成模式适用场景】
1、你想表示对象的部分-整体层次结构
2、你希望用户忽略组合对象和单个对象的不同,用户将统一地使用组合结构中的所有对象。

【合成模式与其它模式】
装饰器模式:Decorator模式经常与Composite模式一起使用。当装饰与合成一起使用时,它们通常有一个公共的父类。因此装饰必须支持具有add,remove和getChild操作的Component接口
享元模式:Flyweight模式让你共享组件,但不再引用他们的父部件
迭代器模式:Itertor可用来遍历Composite
访问者模式:Visitor将本来应该分布在Composite和Leaf类中的操作和行为局部化。

【安全式的合成模式】
在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的。因为树叶类型的对象根本就没有管理子类的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。编译通不过,就不会出现运行时期错误
这样的缺点是不够透明,因为树叶类和合成类将具有不同的接口。

【安全式的合成模式结构图】

安全式的合成模式

安全式的合成模式


【安全式的合成模式PHP示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
<?php
 
/**
 * 安全的合成模式的PHP实现 2010-08-10 sz
 * @author 胖子 phppan.p#gmail.com  http://www.phppan.com                                        
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
 
/**
 * 抽象组件角色
 */
interface Component {
 
    /**
     * 返回自己的实例
     */
    public function getComposite();
 
    /**
     * 示例方法
     */
    public function operation();
}
 
/**
 * 树枝组件角色
 */
class Composite implements Component {
    private $_composites;
 
    public function __construct() {
        $this->_composites = array();
    }
 
    public function getComposite() {
        return $this;
    }
 
    /**
     * 示例方法,调用各个子对象的operation方法
     */
    public function operation() {
        echo 'Composite operation begin:<br />';
        foreach ($this->_composites as $composite) {
            $composite->operation();
        }
        echo 'Composite operation end:<br /><br />';
    }
 
    /**
     * 聚集管理方法 添加一个子对象
     * @param Component $component  子对象
     */
    public function add(Component $component) {
        $this->_composites[] = $component;
    }
 
    /**
     * 聚集管理方法 删除一个子对象
     * @param Component $component  子对象
     * @return boolean  删除是否成功
     */
    public function remove(Component $component) {
        foreach ($this->_composites as $key => $row) {
            if ($component == $row) {
                unset($this->_composites[$key]);
                return TRUE;
            }
        }
 
        return FALSE;
    }
 
    /**
     * 聚集管理方法 返回所有的子对象
     */
    public function getChild() {
       return $this->_composites;
    }
 
}
 
class Leaf implements Component {
    private $_name;
 
    public function __construct($name) {
        $this->_name = $name;
    }
 
    public function operation() {
        echo 'Leaf operation ', $this->_name, '<br />';
    }
 
    public function getComposite() {
        return null;
    }
}
 
 
/**
 * 客户端
 */
class Client {
 
    /**
     * Main program.
     */
    public static function main() {
        $leaf1 = new Leaf('first');
        $leaf2 = new Leaf('second');
 
        $composite = new Composite();
        $composite->add($leaf1);
        $composite->add($leaf2);
        $composite->operation();
 
        $composite->remove($leaf2);
        $composite->operation();
    }
 
}
 
Client::main();
?>

【透明式的合成模式】
在Composite类里面声明所有的用来管理子类对象的方法。这样做的是好处是所有的组件类都有相同的接口。在客户端看来,树叶类和合成类对象的区别起码在接口层次上消失了,客户端可以同等的对待所有的对象。这就是透明形式的合成模式
缺点就是不够安全,因为树叶类对象和合成类对象在本质上是有区别的。树叶类对象不可能有下一个层次的对象,因此调用其添加或删除方法就没有意义了,这在编译期间是不会出错的,而只会在运行时期才会出错。

【透明式的合成模式结构图】

透明式的合成模式

透明式的合成模式

【透明式的合成模式PHP示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
 
<?php
 
/**
 * 透明的合成模式的PHP实现 2010-08-10 sz
 * @author 胖子 phppan.p#gmail.com  http://www.phppan.com                                               
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
 
/**
 * 抽象组件角色
 */
interface Component {
 
    /**
     * 返回自己的实例
     */
    public function getComposite();
 
    /**
     * 示例方法
     */
    public function operation();
 
      /**
     * 聚集管理方法 添加一个子对象
     * @param Component $component  子对象
     */
    public function add(Component $component);
 
    /**
     * 聚集管理方法 删除一个子对象
     * @param Component $component  子对象
     * @return boolean  删除是否成功
     */
    public function remove(Component $component);
 
    /**
     * 聚集管理方法 返回所有的子对象
     */
    public function getChild();
 
}
 
/**
 * 树枝组件角色
 */
class Composite implements Component {
    private $_composites;
 
    public function __construct() {
        $this->_composites = array();
    }
 
    public function getComposite() {
        return $this;
    }
 
    /**
     * 示例方法,调用各个子对象的operation方法
     */
    public function operation() {
        echo 'Composite operation begin:<br />';
        foreach ($this->_composites as $composite) {
            $composite->operation();
        }
        echo 'Composite operation end:<br /><br />';
    }
 
    /**
     * 聚集管理方法 添加一个子对象
     * @param Component $component  子对象
     */
    public function add(Component $component) {
        $this->_composites[] = $component;
    }
 
    /**
     * 聚集管理方法 删除一个子对象
     * @param Component $component  子对象
     * @return boolean  删除是否成功
     */
    public function remove(Component $component) {
        foreach ($this->_composites as $key => $row) {
            if ($component == $row) {
                unset($this->_composites[$key]);
                return TRUE;
            }
        }
 
        return FALSE;
    }
 
    /**
     * 聚集管理方法 返回所有的子对象
     */
    public function getChild() {
       return $this->_composites;
    }
 
}
 
class Leaf implements Component {
    private $_name;
 
    public function __construct($name) {
        $this->_name = $name;
    }
 
    public function operation() {
        echo 'Leaf operation ', $this->_name, '<br />';
    }
 
    public function getComposite() {
        return null;
    }
 
      /**
     * 聚集管理方法 添加一个子对象,此处没有具体实现,仅返回一个FALSE
     * @param Component $component  子对象
     */
    public function add(Component $component) {
        return FALSE;
    }
 
    /**
     * 聚集管理方法 删除一个子对象
     * @param Component $component  子对象
     * @return boolean  此处没有具体实现,仅返回一个FALSE
     */
    public function remove(Component $component) {
        return FALSE;
    }
 
    /**
     * 聚集管理方法 返回所有的子对象 此处没有具体实现,返回null
     */
    public function getChild() {
       return null;
    }
 
}
 
 
/**
 * 客户端
 */
class Client {
 
    /**
     * Main program.
     */
    public static function main() {
        $leaf1 = new Leaf('first');
        $leaf2 = new Leaf('second');
 
        $composite = new Composite();
        $composite->add($leaf1);
        $composite->add($leaf2);
        $composite->operation();
 
        $composite->remove($leaf2);
        $composite->operation();
 
    }
 
}
 
Client::main();
?>

可以看到透明式合成模式的Leaf有各聚集管理方法的平庸实现

Python核心编程读书笔记:第二章,快速入门

第二章学习笔记
【2.1 使用print输出】
print调用str()函数显示对象
print默认在输出的内容后面添加回车,如果不想输出回车,在输出内容后面添加逗号,如果要输出多个内容,使用逗号连接,不过如果带逗号的print语句会在输出的元素之间自动添加一个空格
print与字符串格式操作符(%)结合使用,可实现字符串操作功能(这一点和C语言的printf()函数非常相似)

【2.2 程序输入和raw_input()内建函数】
raw_input读取标准输入,并将读取到的数据赋值给指定的变量,如:

1
2
3
user = raw_input('please input name')
print user
help(raw_input)

Help on built-in function raw_input in module __builtin__:

raw_input(…)
raw_input([prompt]) -> string
raw_input从标准输入读取一个字符串并自动删除串尾的换行字符

【2.3 注释】
单行注释: Python使用#符号标示注释,从#开始,直到一行结束的内容都是注释
多行注释:使用三个单引号或双引号
文档注释:
函数内部的第一行开始的字符串为 DocStrings
DocStrings 一般为多行
DocString 为三引号扩起来的多行字符串
第一行为概述
第二行为空行
第三行开始是详细描述
DocStrings 的存在证明了函数也是对象
函数的 __doc__ 属性为该 DocStrings
例如 print printTest.__doc__ 为打印 printTest 函数的 DocStrings
如下所示代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/python
# -*- coding: utf-8 -*-
u"""文档注释 文档字符串"""
 
import sys
__author__ = "phppan"
__date__ = "$2010-8-1 17:54:58$"
 
def printTest(string):
    u'''
        printTest 函数注释 文档字符串
        注释第二行
    '''
    print string
 
if __name__ == "__main__":
 
    printTest('hello world')
    printTest(__doc__)  #单行注释
    '''
多行注释
    '''
    printTest(printTest.__doc__)
    print __date__
    print __author__

中文注释问题:
Python里有两种字符串,一种是Unicode字符串,一种是一般的字符串。
Python里字符串的encode函数负责将unicode字符串转化为另外一种Unicode编码形式。
decode函数负责将一般的字符串进行解码,结果为unicode编码。还有一点是unicode()负责将一般的字符串解码为指定格式的unicode字符串。
如果字符串是这样定义:s=’中文’
如果是在utf8的文件中,该字符串就是utf8编码,如果是在gb2312的文件中,则其编码为gb2312。
如果字符串是这样定义:s=u’中文’
则该字符串的编码就被指定为unicode了,即python的内部编码
isinstance(s, unicode) #用来判断是否为unicode

print会对输出的文本做自动的编码转换, print转换的目的编码和环境变量有关,Windows XP是转换为gbk的。可以使用用locale模块的getdefaultlocale方法获得当前环境的编码。而print在输出时会把字符串自动转换为这种编码。

【2.4 操作符】
对于一些数据类型,有些操作符是被重载了的,比如字符串和列表
对于不等于操作符,python支持两种 != 和 <>,建议使用 !=
合理使用括号,增强代码的可读性

【2.5 变量和赋值】
类C语言
以字母开头,可以是数字、字母或下划线
大小写敏感
不需要预先声明变量的类型,变量的类型和值在赋值那一刻被初始化
不支持自增1和自减1操作符

【2.6 数字】
Python支持5种数字类型:有符号整形、长整型、布尔、浮点和复数
其中长整型类似于java中的BigInteger类型,它仅受限于用户计算机的虚拟内存总数
decimal类型需要先导入decimal模块才可以使用

【2.7 字符串】
Python中字符串被定义为引号之间的字符集合。Python支持成对的单引号、双引号和三引号
使用索引操作符({[])和切片操作符([:])可以得到子串
字符串有其我有的索引规则:第一个字符的索引是0(和C语言类似),最后一个字符的索引是-1
加号(+)用于字符串连接运算 星号(*)用于字符串重复

【2.8 列表和元组】
从0开始索引,可以存储不同类型的对象
列表元素使用中括号([])包裹,元素的个数和元素的值都可以改变
元组元素使用小括号(())包裹,不可以更改,可以看成是只读的列表

【2.9 字典】
字典是Python中的映射数据类型,工作原理类似于Hash表,可以将其作为PHP的数组使用
字典由键值对构成,几乎所有对象都可以用作键,不过一般使用数字或字符串

【2.10 代码块及缩进对齐】
Python通过缩进对齐表达代码逻辑

【2.11 if语句】
if expression:
if_suite
elif expression2:
elif_suite
else:
else_suite

【2.12 while循环】
while expresion:
while_suite

【2.13 for循环和range()内建函数】
for循环与传统的for循环不同,更像是PHP中的foreach

for eachNum in range(3):
print eachNum

【2.14 列表解析】
[x ** 2 for x in range(4)]
[x ** 2 for x in range(4) if x ** 2 > 1]

【2.15 文件和内建函数file(),open()】
handle = open(filenaem, mode = ‘r’) 返回一个文件句柄

1
2
3
4
5
    filename = raw_input('Enter file name:')
    fobj = open(filename, 'r')
    for eachLine in fobj:
        print eachLine,
    fobj.close()

【2.16 错误和异常】
将代码“封装”在try-except语句当中,就可以增加错误检测及异常处理

【2.17 函数】
一个函数的语法由def关键字及紧随其后的函数名,再加上该函数所需要的参数组成
def function_name([arguments]):
“optional documentation string”
function_suite

函数的参数可以有一个默认值

【2.18 类】
类是面向对象核心,它扮演相关数据及逻辑容器的角色。
定义类:
class ClassName(base_class[es]):
“optional documentation string”
static_memeber_declarations
method_declarations

所有名字开始和结束都有两个下划线的方法都是特殊方法
self是类实例自身的引用
当一个类的实例被创建时,__init__()就会被自动调用

【2.19 模块】
模块是一种组织形式,它将彼此有关系的python代码组织到一个个独立文件当中。模块可以包含可执行代码、函数和类,或者这些东西的组合。
导入模块:import module_name
访问模块函数或模块变量:

1
2
3
    import sys
    sys.stdout.write('hello')
    print sys.platform

【2.20 实用函数】
dir([obj]) 显示对象的属性,如果没有提供参数,则显示全局变量的名字
help([obj]) 以一种整齐美观的形式,,显示对象的文档字符串,如果没有提供任何参数,则会进入交互帮助
int(obj) 将一个对象转化成整形
len(obj) 返回对象的长度
open(fn, mode) 以mode方式打开一个文件名为fn的文件
range([start,]stop[,step]) 返回一个整形列表,起始值为start,结束值为stop -1,start默认值为0,step默认值为1
str(obj) 将一个对象转换为字符串
type(obj) 返回对象的类型(返回值本身是一个type对象)

PHP设计模式笔记:使用PHP实现享元模式

PHP设计模式笔记:使用PHP实现享元模式

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

【享元模式结构图】

享元模式

享元模式

【享元模式中主要角色】
抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过调用商业以参数形式传入
具体享元(ConcreteFlyweight)角色:实现Flyweight接口,并为内部状态(如果有的话)拉回存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的
不共享的具体享元(UnsharedConcreteFlyweight)角色:并非所有的Flyweight子类都需要被共享。Flyweigth使共享成为可能,但它并不强制共享。
享元工厂(FlyweightFactory)角色:负责创建和管理享元角色。本角色必须保证享元对象可能被系统适当地共享
客户端(Client)角色:本角色需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外部状态

【享元模式的优点和缺点】
享元模式的优点:Flyweight模式可以大幅度地降低内存中对象的数量。

享元模式的缺点:
1、Flyweight模式使得系统更加复杂
2、Flyweigth模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长

【享元模式适用场景】
当以下情况都成立时使用Flyweight模式:
1、一个应用程序使用了大量的对象
2、完全由于使用大量的对象,造成很大的存储开销
3、对象的大多数状态都可变为外部状态
4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
5、应用程序不依赖于对象标识。

【享元模式与其它模式】
单例模式(Singleton):客户端要引用享元对象,是通过工厂对象创建或者获得的,客户端每次引用一个享元对象,都是可以通过同一个工厂对象来引用所需要的享元对象。因此,可以将享元工厂设计成单例模式,这样就可以保证客户端只引用一个工厂实例。因为所有的享元对象都是由一个工厂对象统一管理的,所以在客户端没有必要引用多个工厂对象。不管是单纯享元模式还是复合享元模式中的享元工厂角色,都可以设计成为单例模式,对于结果是不会有任何影响的。
Composite模式:复合享元模式实际上是单纯享元模式与合成模式的组合。单纯享元对象可以作为树叶对象来讲,是可以共享的,而复合享元对象可以作为树枝对象,因此在复合享元角色中可以添加聚集管理方法。

【享元模式PHP示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
 
/**
 * 享元模式的PHP简单实现 2010-08-03 sz
 * @author 胖子 phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 抽象享元角色
 */
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示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
 
/**
 * 复合享元模式的PHP简单实现 2010-08-03 sz
 * 《Java与模式》中的示意性源码的PHP修改版本
 * @author 胖子 phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 抽象享元角色
 */
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文件执行开始会载入所需的资源,当执行完毕后,这些所有的资源会被全部释放。
而一般来说我们也不会让一个页面执行太长时间。