享元模式(Flyweight Pattern)
首先吐槽下这个名字,享元?共享元素的话感觉还是蛮好的~但是这个英文。。。
意图:更好的重用、管理对象,减少内存开销,节约资源。
主要解决:在有大量重复对象时,通过抽象,对对象统一管理。
何时使用:1、系统中有大量对象。2、这些对象消耗大量内存。3、这些对象的状态大部分可以外部化。4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。5、系统不依赖于这些对象身份,这些对象是不可分辨的。
如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。
这里和我自己理解的有些许差别,直接导致了两种想法。第一种,重点在于标记对象。第二种重点在于重用对象(创建型模式中的原型模式区别不大)。
下面是按照自己理解写的demo:
类图:复习并二次整理的时候画。
代码:
1、创建链接接口以及实现类(对对象进行抽象):
package com.pat.flyweight;
/**
* 链接接口,代表一类链接
* @author ZX
*/
public interface Connector {
void connect();
}
实现类如下:
package com.pat.flyweight;
/**
* 链接实现类-mysql链接
* @author ZX
*
*/
public class MySqlConnector implements Connector{
@Override
public void connect() {
System.out.println("链接到MySql数据库"+this.toString());
}
}
package com.pat.flyweight;
/**
* 链接子类,Oracle链接
* @author ZX
*
*/
public class OracleConnector implements Connector{
@Override
public void connect() {
System.out.println("链接到Oracle数据库"+this.getClass());
}
}
2、工厂类:
package com.pat.flyweight;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 链接工厂-生产链接
* @author ZX
*/
public class ConnectorFactory {
//为方便演示结果,采用简单的数据结构
private Map<String, Connector> pool = new HashMap<>();
/**
* 获得一个Mysql链接
* @return
*/
public Connector getMySqlConnector() {
Connector mySql = pool.get("mysql");
if(pool.get("mysql")==null) {
mySql = new MySqlConnector();
pool.put("mysql", mySql);
}
return mySql;
}
public Connector getOracleConnector() {
Connector mySql = pool.get("oracle");
if(pool.get("oracle")==null) {
mySql = new MySqlConnector();
pool.put("oracle", mySql);
}
return mySql;
}
}
3、测试类:
package com.pat.flyweight;
public class Test {
public static void main(String[] args) {
//创建链接工厂
ConnectorFactory sf =new ConnectorFactory();
//获取Mysql链接
Connector mySqlConnector = sf.getMySqlConnector();
Connector mySqlConnector2 = sf.getMySqlConnector();
Connector mySqlConnector3 = sf.getMySqlConnector();
mySqlConnector.connect();
mySqlConnector2.connect();
mySqlConnector3.connect();
//获取oracle链接
Connector oracleConnector = sf.getOracleConnector();
Connector oracleConnector2 = sf.getOracleConnector();
Connector oracleConnector3 = sf.getOracleConnector();
oracleConnector.connect();
oracleConnector2.connect();
oracleConnector3.connect();
}
}
4、结果:
链接到MySql数据库com.pat.flyweight.MySqlConnector@7852e922
链接到MySql数据库com.pat.flyweight.MySqlConnector@7852e922
链接到MySql数据库com.pat.flyweight.MySqlConnector@7852e922
链接到MySql数据库com.pat.flyweight.MySqlConnector@4e25154f
链接到MySql数据库com.pat.flyweight.MySqlConnector@4e25154f
链接到MySql数据库com.pat.flyweight.MySqlConnector@4e25154f
可以看到,这里一直重用了容器中的对象,实现了对象的重用。