《Design Patterns》FlyWeight.积跬步系列

FlyWeight:享元模式

先代码

package h.l.demo.flyweight;

import java.util.HashMap;

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 它是所有具体享元类的超类或者接口,通过这个接口,FlyWeight可以接收并作用于外部状态
 */
public abstract class FlyWeight {
	/**
	 * @param extrinsicState
	 *            外部状态
	 */
	public abstract void operation(int extrinsicState);
}

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 具体享元类
 */
class ConcreteFlyWeight extends FlyWeight {

	@Override
	public void operation(int extrinsicState) {
		System.out.println("具体FlyWeight:" + extrinsicState);
	}

}

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 不共享的具体享元类
 */
class UnSharedConcreteFlyWeight extends FlyWeight {

	@Override
	public void operation(int extrinsicState) {
		System.out.println("不共享的具体FlyWeight:" + extrinsicState);
	}

}
/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 享元工厂:用来创建和管理FlyWeight对宪法,它主要作用时用来确保合理的共享FlyWeight
 */
class FlyWeightFactory {
	private HashMap<String, FlyWeight> map = new HashMap<>();

	public FlyWeightFactory(){
		map.put("X", new ConcreteFlyWeight());
		map.put("Y", new ConcreteFlyWeight());
		map.put("Z", new ConcreteFlyWeight());
	}
	public FlyWeight getFlyWeight(String key){
		if(map.get(key) == null){
			map.put(key, new ConcreteFlyWeight());
		}
		return map.get(key);
	}
}

测试类:

package h.l.demo.flyweight;
/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年1月31日
 * @Description: 测试
 */
public class TestMainEnter {

	public static void main(String[] args) {
		int extrinsicState = 1503;
		
		FlyWeightFactory f =new FlyWeightFactory();
		
		FlyWeight fx = f.getFlyWeight("X");
		fx.operation(--extrinsicState);
		
		FlyWeight fy = f.getFlyWeight("Y");
		fx.operation(--extrinsicState);
		
		FlyWeight fz = f.getFlyWeight("Z");
		fx.operation(--extrinsicState);
		
		FlyWeight uf = new UnSharedConcreteFlyWeight();
		uf.operation(--extrinsicState);
	}

}

测试结果:
在这里插入图片描述

后分析

  • 个人建议:写代码是件幸福的事,So,do it

享元模式,定义:应用共享技术有效地支持大量细粒度的对象。通俗讲,就是一类被实例化太多次(这叫大量细粒度的对象),就可以使用共享技术,通过分离内部状态和外部状态,即这些实例化对象中共同的代码作为内部状态,有差异的地方作为外部状态。这样就可以只创建少部分的实例化就能实现上述大量细粒度对象才能完成的功能。

享元模式可以避免大量非常类似类的开销,在程序设计中有时需要生成的阿亮细粒度的类实例来表示数据。如果发现这些实例除了几个参数外基本上是相同的,有时就能够大幅度的减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将他们传进来,就可以通过共享大幅度地减少单个实例的数目。

举个例子:围棋,如果每一个棋子都是一个实例,那一局棋就需要361个实例对象(有361个位置可以放棋子)。N个人同时下棋,那就是Nx361,部署在服务器上,内存有限,无法支持更多的用户玩耍。那么这个时候就可以使用享元模式,棋子可以减少到只有两个实例,黑色和白色。每一个棋子的位置,作为外部状态传入。仔细一想是不是感觉瞬间优化不少。但使用享元模式需要维护一个记录了系统已有的所有享元的列表(每一次使用享元都需要进行一次查找,即在demo中的map中进行查找),而这本身是消耗资源,也是系统更为复杂,因此使用享元模式营改增爱有足够多的对象实例可以共享的时候才值得使用该模式。

其他例子:参考自《大话设计模式》博客网站,每一个用户都有一个类似界面的博客,总不能每个人都去new一个博客网站的实例,服务器吃不消,那么共享模式就可以使用了,将有差异的部分移到实例外,将差异在方法调用时传入即可。


注:以上文章仅是个人总结,若有不当之处,望不吝赐教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章