享元模式
享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
这里笔者曾经用Unity做过一款子弹射击的游戏,用的就是这个模式.在FPS游戏中,射出去的子弹会产生一个实体,过一会一定要销毁不然会占用电脑内存.所以出现了对象池技术,限定多少发子弹会产生,然后销毁后进入池子,然后再被使用,大大减少开销.
//车子抽象类
public abstract class BikeFlyWeight {
//内部状态
protected Integer state = 0;//0是未使用,1是使用中
//userName外部状态
abstract void ride(String userName);
abstract void back();
public Integer getState(){
return state;
}
}
//共享单车实体类
public class MoBikeFlyWeight extends BikeFlyWeight{
//定义新的内部状态,车架号
private int bikeId;
public MoBikeFlyWeight(int bikeId)
{
this.bikeId = bikeId;
}
@Override
void ride(String userName) {
state = 1;
System.out.println(userName+"骑"+bikeId+"号 自行车出行!");
}
@Override
void back() {
state = 0;
System.out.println(bikeId+"号 自行车归还!");
}
}
//工厂模式+单例模式的使用
public class BikeFlyWeightFactory {
private static BikeFlyWeightFactory instance = new BikeFlyWeightFactory();
private Set<BikeFlyWeight> pool = new HashSet<>();
public static BikeFlyWeightFactory getInstance(){
return instance;
}
private BikeFlyWeightFactory(){
for(int i = 0;i<2;i++)
{
pool.add(new MoBikeFlyWeight(i));
}
}
public BikeFlyWeight getBike(){
for(BikeFlyWeight bike :pool)
{
if(bike.getState()==0)
return bike;
}
return null;
}
}
//用户类
public class FlyWeightPattern {
public static void main(String[] args) {
BikeFlyWeight bike1 = BikeFlyWeightFactory.getInstance().getBike();
bike1.ride("张三");
bike1.back();
BikeFlyWeight bike2 = BikeFlyWeightFactory.getInstance().getBike();
bike2.ride("赵四");
BikeFlyWeight bike3 = BikeFlyWeightFactory.getInstance().getBike();
bike3.ride("王五");
bike3.back();
System.out.println(bike1==bike2);
System.out.println(bike2==bike3);
}
}
结果:
张三骑1号 自行车出行!
1号 自行车归还!
赵四骑1号 自行车出行!
王五骑0号 自行车出行!
0号 自行车归还!
true
false
由结果可见,第一个车子归还后被赵四所用,所以bike1=bike2
享元模式的主要优点是:相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
其主要缺点是:
- 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
- 读取享元模式的外部状态会使得运行时间稍微变长。
各种池子技术与享元模式大同小异