- 什么是享元模式
- 享元模式的例子
- 享元模式的优缺点
- 享元模式使用场景
- 闲言碎语
什么是享元模式
在日常生活中我们在不同的场景中可能会用到相同的东西,例如打火机,我们在点烟和生火做饭的时候都需要用到它.但实际上我们不能为此配备两个打火机,而是只需要一个打火机便可以满足我们的需求.同理,在程序中我们也可能在不同的场景使用到同一个对象,当然我们为其都建立一个对象是完全可以的.但是如果场景过多的话那么就需要建立很多相同的对象,这对系统来说是一个不小的负担.此时,为了解决这个问题我们就需要用到享元模式.
意图:运用共享技术有效地支持大量细粒度的对象。
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
- FlyWeight:享元接口或者(抽象享元类),定义共享接口
- ConcreteFlyWeight:具体享元类,该类实例将实现共享
- UnSharedConcreteFlyWeight:非共享享元实现类(由于本文实例原因,省略去掉)
- FlyWeightFactory:享元工厂类,控制实例的创建和共享
享元模式的例子
接口
package com.designPattern.flyweight;
/**
* 享元模式的接口
*
* @author Jason
*
*/
public interface Flyweight {
public void use();// 对物品的使用方法
}
实体对象
package com.designPattern.flyweight;
/**
* 可以具体的代指任务物品的基类
*
* @author Jason
*
*/
public class Goods implements Flyweight {
private String name;
public Goods(String name) {
System.out.println("创建" + name);
this.name = name;
}
@Override
public void use() {
System.out.println(name + "被使用");
}
}
工厂类
package com.designPattern.flyweight;
import java.util.Hashtable;
/**
* 物品的工厂类,负责物品的维护
*
* @author Jason
*
*/
public class GoodsFactory {
// 负责对物品的存储
private Hashtable<String, Flyweight> flyweights = new Hashtable<String, Flyweight>();
// 取得对应的物品,如果没有则进行创建
public Flyweight getFlyweight(String name) {
if (name == null) {
return null;
}
Flyweight flyweight = flyweights.get(name);
if (flyweight == null) {
flyweight = new Goods(name);
flyweights.put(name, flyweight);
}
return flyweight;
}
public int getSize() {
return flyweights.size();
}
}
测试类
package com.designPattern.flyweight;
import org.junit.Test;
/**
* 测试类
*
* @author Jason
*
*/
public class TestCase {
@Test
public void test() {
GoodsFactory factory = new GoodsFactory();
Flyweight flyweight1 = factory.getFlyweight("剪刀");// 创建剪刀对象
Flyweight flyweight2 = factory.getFlyweight("剪刀");// 不创建剪刀对象
System.out.println(flyweight1 == flyweight2);// 判断取得的物品是否相同
}
}
享元模式的优缺点
优点
享元模式的优点在于它大幅度地降低内存中对象的数量
缺点
享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
享元模式使用场景
-
享元模式由于其共享的特征,可以在任何“池”中操作,比如:线程池,数据库连接池。
-
String类的设计也是享元模式。
闲言碎语
这是最简单的使用,在日常开发中享元模式必然会结合其他的模式一起组合使用.很少会单独出现!