设计模式——享元模式

享元模式: 场景:内存属于稀缺资源,如果有很多个完全相同或相似的对象,我们可以通过享元模式来节省内存。

      核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。 享元对象能做到共享的关键字是区分了内部状态和外部状态。

      内部状态:可以共享,不会随着环境变化而改变。

      外部状态:不可以共享,会随着环境变化而改变。

享元模式的实现:

      1.FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对

      2.FlyWeight抽象享元类:通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置对象的外部状态。

      3.ConcreteFlyweight具体享元类:为内部状态提供的成员变量进行存储。

      4.UnsharedConcreteFlyWeight非共享享元类:不能被共享的子类可以设计成为非共享享元类。

应用场景:线程池、数据库连接池、String类的设计。

优点:极大的减少内存中对象的数量。相同或相似的对象内存中只有一份,一个实例可以提供许多虚拟实例,极大的节约资源,提高系统的性能。      

         外部状态相对独立,不影响内部状态。

缺点:模式较复杂。使程序的逻辑复杂化,每次读取外部状态使运行时间变长,用时间换取了空间。      

         一旦实现了享元模式,单个逻辑实例将无法拥有独立的行为。

看一个简单明了的Demo:

 

/**
 * 享元类
 * @author wxisme
 *
 */
public interface FlyWeight {
	void setSex(String sex);
	String getSex();
	void display(Character c);

}
/**
 * 具体享元类  获取内部状态、设置外部状态
 * @author wxisme
 *
 */

class HumanFlyWeight implements FlyWeight {
	private String sex;

	
	public HumanFlyWeight(String sex) {
		super();
		this.sex = sex;
	}

	@Override
	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String getSex() {
		return sex;
	}

	@Override
	public void display(Character c) {
		System.out.println(c.getCharacter() + "的" + sex + "。");
	}
	
}



/**
 * 外部状态
 * @author wxisme
 *
 */
public class Character {
	private String character;

	
	public Character(String character) {
		super();
		this.character = character;
	}

	public String getCharacter() {
		return character;
	}

	public void setCharacter(String character) {
		this.character = character;
	}
	
	

}


import java.util.HashMap;
import java.util.Map;

/**
 * 享元工厂类
 * @author wxisme
 *
 */

public class HumanFlyWeightFactory {
	static Map<String, FlyWeight> map = new HashMap<>();
	
	public static FlyWeight getHuman(String sex) {
		if(map.get(sex) != null) {
			return map.get(sex);
		}
		else {
			FlyWeight h = new HumanFlyWeight(sex);
			map.put(sex, h);
			return h;
		}
		
	}

}


public class Client {
	public static void main(String[] args) {
		HumanFlyWeightFactory factory = new HumanFlyWeightFactory();
		//实质是共享相同的内部状态,封装变化的外部状态,节省资源。
		FlyWeight flyweight1 = factory.getHuman("女人");
		FlyWeight flyweight2 = factory.getHuman("女人");
		//两个只包含相同内部状态的对象其实是一个对象。
		System.out.println(flyweight1);
		System.out.println(flyweight2);
		//设置变化的外部状态。
		flyweight1.display(new Character("性感"));
		flyweight2.display(new Character("漂亮"));

		
	}
}

 

 运行结果:

com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
性感的女人。
漂亮的女人。

 

posted @ 2015-06-03 17:57  Pickle  阅读(441)  评论(0编辑  收藏  举报