Flyweight ??
Flyweight是“轻量级”的意思,指的是拳击比赛中选手体重最轻的等级。顾名思义,该设计模式的作用是为了让对象变“轻”。
-
简单概括:通过尽量共享实例来避免new出实例
这里的共享不是任何对象都是共享的,在满足业务逻辑要求的情况下,将会重复利用的对象在对象的生命周期中保持替换不变,二不需要重新安排创造新的对象,创建新的对象既浪费时间又浪费内存空间。时间也是一种资源。使用new关键字生成实例会花费时间。通过Flyweight模式共享实例可以减少使用new关键字生成实例的次数。这样,就可以提高程序运行速度。 -
两个点:
即为应该共享的信息与不应该共享的信息
1.intrinsic(应该共享)
Intrinsic的意思是“本质的”“固有的”。换言之,它指的是不论实例在哪里、不论在什么情况下都不会改变的信息,或是不依赖于实例状态的信息。
2.extrinsic(不应该共享)
Extrinsic的意思是“外在的”“非本质的”。也就是说,它是当实例的位置、状况发生改变时会变化的信息,或是依赖于实例状态的信息。 -
防止创建多个实例:
getBigchar方法是synchronized方法。如果不使用synchronized修饰符,在进行多个线程的处理时候将会出现多个实例
理清职责
- 实现功能:我们以文件形式保存了大型字符0~9,和“-”,的字体数据 通过代码读入内存并且显示出来
|名字======>>.说明
|Bigchar |表示“大型字符”的类
|BigcharFactory |表示生成和共用Bigchar类的实例的类
|Bigstring |表示多个Bigchar组成的“大型字符串”的类
|MainT |测试程序行为的类
................
................
................
................
..##########....
................
................
................
....######......
..##......##....
..##......##....
..##......##....
..##......##....
..##......##....
....######......
................
....######......
..##......##....
..##......##....
....########....
..........##....
..##......##....
....######......
................
UML
Code
- BigChar
public class BigChar {
// 字符名字
private char charname;
// 大型字符串对应的数据
private String fontdata;
public BigChar(char charname) {
this.charname = charname;
try {
BufferedReader buf=new BufferedReader(new FileReader(
"Resources\FlyWeight\big"+charname+".txt"
));
String line;
StringBuffer buffer = new StringBuffer();
while ((line=buf.readLine())!=null){
buffer.append(line);
buffer.append("
");
}
buf.close();
this.fontdata= buffer.toString();
}catch (IOException e){
e.printStackTrace();
this.fontdata=charname+"?";
}
}
// 显示字符
public void print(){
System.out.println(fontdata);
}
}
- BigcharFactory
public class BigcharFactory {
// 管理已经生成的实例 实现共享 但要保证不被垃圾回收器回收
private HashMap<String,BigChar> pool=new HashMap<>();
private BigcharFactory(){};
private static BigcharFactory singleton=new BigcharFactory();
public static BigcharFactory getInstance(){
return singleton;
}
// 生成实例
public synchronized BigChar getBigChar(char charname){
BigChar aChar = pool.get("" + charname);
if (aChar == null) {
aChar=new BigChar(charname);
pool.put(""+charname,aChar);
}
return aChar;
}
}
- BigString2、BigString
public class BigString {
private BigChar[] bigChars;
/**
* 根据入参字符串 构造大型字符串
*/
public BigString(String string){
bigChars=new BigChar[string.length()];
// 实现共享实例
BigcharFactory factory = BigcharFactory.getInstance();
for (int i = 0; i < bigChars.length; i++) {
bigChars[i] = factory.getBigChar(string.charAt(i));
}
}
// show
public void print(){
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
public class BigString2 {
private BigChar[] bigChars;
/**
* @param string 转入的构造出参数
* @param shared 是否创建共享对象
*/
public BigString2(String string,boolean shared) {
if(shared){
ininShared(string);
}else{
initUnshared(string);
}
}
/**
* 根据入参字符串 构造大型字符串,不使用共享方式
* @param string
*/
public void initUnshared(String string) {
bigChars=new BigChar[string.length()];
for (int i = 0; i < bigChars.length; i++) {
bigChars[i]=new BigChar(string.charAt(i));
}
}
/**
* 根据入参字符串 构造大型字符串,使用共享的方式
*/
public void ininShared(String string){
bigChars=new BigChar[string.length()];
// 实现共享实例
BigcharFactory factory = BigcharFactory.getInstance();
for (int i = 0; i < bigChars.length; i++) {
bigChars[i] = factory.getBigChar(string.charAt(i));
}
}
// show
public void print(){
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
- MainT
public class MainT {
private static BigString2[] bsarray = new BigString2[1000];
public static void main(String[] args) {
System.out.println("共享内存: ");
testAllocation(true);
System.out.println("不共享内存:");
testAllocation(false);
}
private static void testAllocation(boolean b) {
for (int i = 0; i < bsarray.length; i++) {
bsarray[i] = new BigString2("1212123", b);
}
showMemory();
}
private static void showMemory() {
/**
* 实现内存判断
*/
Runtime.getRuntime().gc();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
System.out.println("使用内存= "+used);
}
}
- 运行结果:
···
共享内存:
使用内存= 749616
不共享内存:
使用内存= 3264096
···