享元模式(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可以看到,这里一直重用了容器中的对象,实现了对象的重用。