设计模式之享元模式

如有转载,请申明:

转载至 http://blog.youkuaiyun.com/qq_35064774/article/details/52097024


1 什么是享元模式

 

享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。

享元对象能做到共享的关键是区分内蕴状态外蕴状态。

内蕴状态是存储在享元对象内部的,不会随着环境而改变,所以是可以共享的。

外蕴状态是随环境改变而改变的,所以不可共享。

 

 

2 如何实现享元模式

 

同样我们举个简单的例子。

 

 * 加载图片是非常消耗资源的操作

 * 假设现在总共只有几张图片,但运行过程中,需要频繁的在不同位置展示这些图片

 

题目说明很清楚,由于一张图片小的十几k,大的几M,是非常耗内存的,然而图片总共只有那几张。对于相同的图片,在内存中只需要存在一份即可,这个时候就可以考虑用享元模式。

把图片的所有字节看作是内蕴状态,而图片位置就是外蕴状态。

 

我们就可以定义出图片类,注意这个图片类是我们自己定义的,不要和官方库里面的类混淆了。

 

package com.ittianyu.flyweight;

public class Image {
	private String name;
	private byte[] bytes;
	// name 作为内蕴状态
	public Image(String name) {
		super();
		this.name = name;
		// 为了简单,这里不做读取图片的操作,直接用个byte数组来表示
		bytes = new byte[1024];
	}
	// 这里的x y坐标作为外蕴状态
	public void show(int x, int y) {
		System.out.println(name + "  show in" + "(" + x + ", " + y + ")");
	}
}


 

为了控制对象的产生,也就是为了共享,我们需要一个工厂类来生产对象。

 

package com.ittianyu.flyweight;

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

public class ImageFactory {
	private static ImageFactory factory;
	private Map<String, Image> maps = new HashMap<String, Image>();
	
	// 懒汉单例模式
	private ImageFactory(){}
	public synchronized static ImageFactory getInstance() {
		if(null == factory)
			factory = new ImageFactory();
		return factory;
	}
	
	public Image create(String name) {
		if(maps.containsKey(name))
			return maps.get(name);
		
		Image image = new Image(name);
		maps.put(name, image);
		return image;
	}
}

 

这个类里面,我们通过create方法来创建Image对象,创建的时候,我们先检查这个图片是否已经存在,如果存在,直接返回这个对象的引用,否则就创建一个,并放到map集合中。

 

最后是测试类。


package com.ittianyu.flyweight;

public class Test {
	public static void main(String[] args) {
		ImageFactory factory = ImageFactory.getInstance();
		
		Image image1 = factory.create("image1.png");
		Image image2 = factory.create("image2.png");
		Image image3 = factory.create("image1.png");
		Image image4 = factory.create("image1.png");
		
		image1.show(0, 0);
		image2.show(10, 10);
		image3.show(4, 2);
		image4.show(8, 3);	
	}
}


这个测试类中,我们在调用show方法时,需要传入坐标参数,这就是外蕴状态。

 

 

3 在什么情况下使用享元模式

 

引用《Java与模式》中的说明。

 * 一个系统有大量的对象。

 * 这些对象耗费大量的内存。

 * 这些对象的状态中大部分都可以外部化。

 * 这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中剔除时,每一个组都可以仅用一个对象代替。

4 享元模式的优点和缺点

 

优点:

 * 可以大幅度降低内存中对象的数量。

 

缺点:

 * 使得系统更加复杂。

 * 享元对象将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值