简介
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
案例
坦克大战设计
每个坦克都是一个对象
以下两种可以是共享的 那么我么可以称他们为:内部状态
- 型号
- 颜色
另外一些则是不可共享的 我们称之为:外部状态
- 坐标
代码实现
享元设计模式一般包括以下的四块内容
- FlyWeight 抽象享元类
这个通常是一个接口或者是一个抽象类,这个可以提供内部状态,设置外部状态。
我这边为了简洁,只写一个内部状态。
public interface TankFlyWeight {
void setColor(String color);
String getColor();
void display(Coordinate coordinate);
}
- ConcreteFlyWeight具体享元类
具体享元类主要是为内部状态,也就是 共有的状态 提供一个存储的地方
class ConcreateTank implements TankFlyWeight{
private String model;
private String color;
public void setColor(String color) {
this.color = color;
}
public ConcreateTank(String color) {
super();
this.color = color;
}
public void display(Coordinate coordinate) {
System.out.println("坦克颜色:"+color);
System.out.println("坦克位置:"+coordinate.getX()+"=="+coordinate.getY());
}
public String getColor() {
// TODO Auto-generated method stub
return color;
}
- UnsharedConcreateFlyWeight 非共享享元类
用于存储外部状态,也就是经常改变的状态
public class Coordinate {
private int x,y;
public Coordinate(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
- FlyWeightFactory 享元工厂类
创建并管理享元对象,一般是键值对的形式
import java.util.HashMap;
import java.util.Map;
public class TankFlyWeightFactory {
private static Map<String, TankFlyWeight> map = new HashMap<String, TankFlyWeight>();
public static TankFlyWeight getTank(String color) {
if (map.get(color)!=null) {
return map.get(color);
}
else {
TankFlyWeight tankFlyWeight = new ConcreateTank(color);
map.put(color, tankFlyWeight);
return map.get(color);
}
}
}
- 最后 定义一个客户类进行测试
创建一个客户类,通过享元工厂进行生产取出
public class Client {
public static void main(String[] args) {
TankFlyWeight tank1 = TankFlyWeightFactory.getTank("黄色");
TankFlyWeight tank2 = TankFlyWeightFactory.getTank("黄色");
System.out.println(tank1);
System.out.println(tank2);
tank1.display(new Coordinate(10, 12));
tank2.display(new Coordinate(13,15));
}
}
输出结果是
com.guxiang.flyweight.ConcreateTank@5d888759
com.guxiang.flyweight.ConcreateTank@5d888759
坦克颜色:黄色
坦克位置:10==12
坦克颜色:黄色
坦克位置:13==15
我们可以看到,两个对象的 hashcode值是一样的,这证明它们其实是同一个对象,这样就避免了内存中存放过多的相似的对象,而导致内存不够用的情况下。
UML图实现如下
例子
- 享元模式在身边随处可见,最常用的要属 String类 string类中有一个常量池的概念,其内部也是一个享元设计模式实现的。
- 常见的还有 线程池 ThreadLocal
- 以及数据连接池