Flyweight模式

一、FlyWeight模式定义:

运用共享技术有效地支持大量细粒度对象。

二、模式解说

也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式。Flyweight的内部状态是用来共享的,Flyweightfactory负责维护一个对象存储池(FlyweightPool)来存放内部状态的对象。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度。

三、结构图

Flyweight模式_第1张图片

原理:
享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State).
一个内蕴状态是存储在享元对象内部的,并且不会随环境改变而有所不同.因此,一个享元可以具有内蕴状态并可以共享.
一个外蕴状态是随环境改变而改变的,不可以共享状态.享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传到享元对象内部.
外蕴状态不可以影响享元对象的内蕴状态,他们是相互独立的.所有的内蕴状态在对象创建完后就不可再改变.

举一个现实中的例子,某淘宝店经营一款畅销女式皮鞋,每天需要处理大量的订单信息,在订单中需要注明客户购买的皮鞋信息,我们将皮鞋产品抽象出来:


class Shoe {

	String color;// 颜色
	int size;// 尺寸

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

}

public class ConcreteShoe extends Shoe {

	String position;// 库存位置

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

}
class ShoeFactory {

	Collection<ConcreteShoe> shoes = new ArrayList<ConcreteShoe>();

	Shoe getSheo(String color, int size, String position) {
		// 首先在缓存中查找对象
		for (ConcreteShoe shoe : shoes) {
			if (shoe.getColor() == color && shoe.getSize() == size) {
				// 在缓存中命中对象后还原对象的外部属性
				shoe.setPosition(position);
				return shoe;
			}
		}
		// 如果缓存未命中则新建对象并加入缓存
		ConcreteShoe shoe = new ConcreteShoe();
		shoe.setColor(color);
		shoe.setSize(size);
		shoe.setPosition(position);
		shoes.add(shoe);
		return shoe;
	}
}

当我们在自己的业务场景中应用享元模式时,一定要注意分清对象的内部状态和外部状态,享元模式强调缓存的版本只能包含对象的内部状态。

        事实上,Java中的String和Integer类都是享元模式的应用的例子,String类内部对所有的字符串对象进行缓存,相同的字符串在内存中只会保留一个版本。类似的,Integer类在内部对小于255的整数也进行了缓存。

五、 适用性

Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用Flyweight模式。

1)  一个应用程序使用了大量的对象。

2)  完全由于使用大量的对象,造成很大的存储开销。

3)  对象的大多数状态都可变为外部状态。

4)  如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

5)  应用程序不依赖对象标识。

六、优缺点

1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

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



你可能感兴趣的:(设计模式,UML,flyweight,享元)