- 重复利用对象
- gof(c++)中的例子是字处理软件,word(不是自处理,前面一篇更正)
UML类图
字处理软件
- word等字处理软件
- 打一个字符’A’,这个字符可大可小,可以有下划线,可以加粗……(装饰器模式?)
- 假如每敲一个字符都产生一个对象,那么小对象会特别多
- 把所有的小对象装到一个池子中去,当要使用某一个小对象的时候就从池子中去拿,不要再new了
- 享元:共享元对象
坦克项目使用享元(为了设计模式而设计模式)
- 生成500个子弹
- 谁要用子弹就去共享池中去拿
- 子弹飞出范围就使他的alive变为false,不再去绘制这颗子弹,但他仍在池子里
- 假如要用的时候所有都活着,再return new Bullet();
- 这本质上就是池化的思想:连接池、线程池 ```java package com.mashibing.dp.flyweight;
import java.util.ArrayList; import java.util.List; import java.util.UUID;
class Bullet{ // 网络上唯一的编号 public UUID id = UUID.randomUUID(); // 默认是alive的,即在使用中 boolean living = true;
@Override
public String toString() {
return "Bullet{" +
"id=" + id +
'}';
}
}
public class BulletPool {
List
public Bullet getBullet() {
for(int i=0; i<bullets.size(); i++) {
Bullet b = bullets.get(i);
// 有空闲子弹时,返回空闲子弹
if(!b.living) return b;
}
// 子弹池里面的子弹都活着的时候(即在使用中的时候),就返回一个新的子弹
return new Bullet();
}
public static void main(String[] args) {
BulletPool bp = new BulletPool();
for(int i=0; i<10; i++) {
Bullet b = bp.getBullet();
System.out.println(b);
}
}
}
<a name="v0qVE"></a>
## java中的String用的就是享元模式
- 字符串常量池
- intern()指的是某一对象里装的常量池中的对象,拿到常量池中的引用(**面试常问**)
- String对象和String常量是不一样的:String对象里面装的常量对象
- **拓展jvm中的字符串常量池在版本变化中的变化**
- 共享经济--->共产主义
```java
package com.mashibing.dp.flyweight;
public class TestString {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1 == s2); //true
System.out.println(s1 == s3); //false
System.out.println(s3 == s4); //false
System.out.println(s3.intern() == s1); //true
System.out.println(s3.intern() == s4.intern()); //true
}
}
结合Composite的享元模式(如上UML图)
- 池中存在着一些组合性的享元(branch和leaf组合)