java之享元模式

享元模式

定义

运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

简单来说就是将大量的小的重复使用的对象统一管理起来,避免用户多次创建重复对象造成的资源浪费;

示例

享元接口

public interface MyFlyWeight {

	public void operation();
}

享元实现类

public class MyFlyWeightImpl implements MyFlyWeight {

	private String state;
	public MyFlyWeightImpl(String state) {
		this.state = state;
	}
	@Override
	public void operation() {
		System.out.println("对象:"+this);
	}

}

享元工厂,保证每次传入相同状态只返回相同的对象;

public class FlyWeightFactory {

	private static final HashMap flyWeights = new HashMap();
	
	public static MyFlyWeight getFlyWeight(String state){
		MyFlyWeight myFlyWeight = flyWeights.get(state);
		if(myFlyWeight == null){
			myFlyWeight = new MyFlyWeightImpl(state);
			flyWeights.put(state, myFlyWeight);
		}
		return myFlyWeight;
	}
	
	public static int getSize(){
		return flyWeights.size();
	}
}

测试类

public class MyFlyWeightTest {

	public static void main(String[] args) {
		MyFlyWeight flyWeight  = null;
		
		System.out.println("first request");
		flyWeight = FlyWeightFactory.getFlyWeight("a");
		flyWeight.operation();
		System.out.println("对象池数量:"+FlyWeightFactory.getSize());
		
		System.out.println("second request");
		flyWeight = FlyWeightFactory.getFlyWeight("b");
		flyWeight.operation();
		System.out.println("对象池数量:"+FlyWeightFactory.getSize());
		
		System.out.println("third request");
		flyWeight = FlyWeightFactory.getFlyWeight("a");
		flyWeight.operation();
		System.out.println("对象池数量:"+FlyWeightFactory.getSize());
	}
}

结果:三次请求有两次相同状态,因此实际上只有2个对象保存,请求相同状态a返回相同的对象

first request
对象:com.huzd.study.flyweight.MyFlyWeightImpl@4a5ab2
对象池数量:1
second request
对象:com.huzd.study.flyweight.MyFlyWeightImpl@1888759
对象池数量:2
third request
对象:com.huzd.study.flyweight.MyFlyWeightImpl@4a5ab2
对象池数量:2

分析

  1. 为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。

与单例对比

  1. 享元模式是共享,但共享的是池,而不是单一,当然这个池的大小可以是1个。享元模式的目的是共享,避免多次创建耗费资源,单例模式的目的是限制创建多个对象以避免冲突等,所以即使都是一个对象,目的也不同。
  2. 如上面的例子中享元模式虽然每次相同状态返回同一个对象,但实际上不同状态还是会有不同对象返回,对象池中也会有多个对象存在,但是单例只允许一个对象存在;

应用

在JAVA语言中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,这个字符串常量池在jdk 6.0以前是位于常量池中,位于永久代,而在JDK 7.0中,JVM将其从永久代拿出来放置于堆中。JAVA会确保一个字符串常量在常量池中只有一个拷贝。String a=“abc”,其中"abc"就是一个字符串常量。

String s1 = "abc";
String s2 = "abc";

如果我们以s1==s2进行比较的话所得结果为:true,因为s1和s2保存的是字符串常量池中的同一个字符串地址。这就类似于我们今天所讲述的享元模式,字符串一旦定义之后就可以被共享使用,因为他们是不可改变的,同时被多处调用也不会存在任何隐患。

你可能感兴趣的:(java,设计模式)