共享对象,避免浪费
1.基本介绍
享元模式适用于需要new大量对象的情况。通过共享实例的方式避免new出实例,浪费资源。
在使用享元模式的时候要注意,当共享实例修改时,将会影响使用该实例的多处地方,所以使用前需要斟酌,什么类需要使用享元模式。
2.实现实例
BigChar类
/**
* @author Jay
* @date 2019/7/2 0:06
* @description 大字符类
*/
public class BigChar {
/**
* 字符名称
*/
private char charname;
/**
* 大型字符对应的字符串(由'#' '.' '\n'组成)
*/
private String fontdata;
/**
* 构造方法,设置字符名称,并初始化数据
*
* @param charname 字符名称
*/
public BigChar(char charname) {
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(new FileReader(System.getProperty("user.dir")
+ "/src/main/java/desiginmode/flyweight/example/char/big" + charname + ".txt"));
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("\n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?\n";
}
}
/**
* 显示大型字符
*/
public void print() {
System.out.print(fontdata);
}
}
BigCharFactory类
生成实例,实现了共享实例的功能.
/**
* @author Jay
* @date 2019/7/2 0:11
* @description 大字符工厂类
*/
public class BigCharFactory {
/**
* 管理已经生成的BigChar的实例
*/
private Map<String, BigChar> pool = new HashMap<>();
/**
* 唯一实例
*/
private static BigCharFactory instance = new BigCharFactory();
/**
* 获取实例
*
* @return 实例
*/
public static BigCharFactory getInstance() {
return instance;
}
private BigCharFactory() {
}
/**
* 生成(共享)BigChar类的实例
*
* @param charname 字符名
* @return 大字符对象
*/
public synchronized BigChar getBigChar(char charname) {
BigChar bc = pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
}
BigString类
由BigChar组成的大型字符串的类的实例.
/**
* @author Jay
* @date 2019/7/2 0:12
* @description 大字符串
*/
public class BigString {
/**
* 大字符数组
*/
private BigChar[] bigChars;
/**
* 构造方法,传入字符串
*
* @param string 字符串
*/
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));
}
}
/**
* 显示
*/
public void print() {
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
测试类
/**
* @author Jay
* @date 2019/7/2 0:13
* @description
*/
public class Test {
public static void main(String[] args) {
BigString bigString = new BigString("123");
bigString.print();
}
}
/*......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
....######......
..##......##....
..........##....
......####......
..........##....
..##......##....
....######......
................
若是要建立1212123这样的字符,则对象为:
其实只创建了3个对象,放入pool中,不同的程序共享此对象.
3.角色介绍
Flyweight(轻量级)
按照通常方式编写程序会导致程序变重,所以如果能够共享实例会比较好,而Flyweight角色表示的就是那些实例会被共享的类。在案例中,由BigChar类扮演此角色。
FlyweightFactory(轻量级工厂)
FlyweightFactory角色是生成Flyweight角色的工厂。在工厂中生成Flyweight角色可以实现共享实例。在案例中,由BigCharFactory类扮演此角色。
Client(请求者)
Client角色使用FlyweightFactory角色来生成Flyweight角色。在案例中,由BigString类扮演此角色。