您的位置:首页 > 其它

设计思想学习—享元模式

2018-01-03 19:13 176 查看

享元模式

大话设计模式上举得是大量的私人项目,这点很是羡慕,没有私人项目的经验所以只能干瞪眼了喽。

享元模式实现相同或者相似对象的重用。也就是说实现相同或者相似对象的代码共享。

享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象。

套用大话设计模式的一段话就是:

享元模式可以避免大量非常相似类的开销。

在程序设计中,有时需要生成大量细粒度的类实例来表示数据。

如果能发现这些实例除了几个参数外基本相同,有时就能够大幅度地减少需要实例化的类的数量。

如果能把那些参数移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度地减少单个实例的数目。

从几个参数外基本相同这句话不难看出,享元模式所需的状态有两部分,分别是相同的内部和不同的外部。

这里出现了几个名词,首先我们来举个栗子说明下粒度的问题:

就比如说车,大家都知道公路上的车颜色有很多种,但是他们都是车,在这里就可以认为是粗粒度的,而颜色这些就可以认为是细粒度的。

然后就是内外部状态:

内部状态就是共享的部分也就是相同的部分。

外部状态就是随着坏境改变的部分

现在来看下享元模式组成:

抽象享元类(Flyweight):所有具体享元类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部专题

具体享元类(ConcreteFlyweight):指定内部状态,为内部状态增加存储空间。

非共享具体享元类(UnsharedConcreteFlyweight):指出那些不需要共享的Flyweight子类。

享元工厂类(FlyweightFactory):用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)。

享元模式最重要的就是享元工厂类了,它是维护实例的。

当实例不存在时,就创建一个放入享元池。

当实例存在,就直接从享元池中取出实例来用。

这个跟java中String的工作方式一样,下面代码他们输出的是true因为指向的是同一个地址:

String one="享元模式";
String two="享元模式";
System.out.println(one == two);


同样的在给String赋值的时候会在内存中去查找是否存在此对象,如果不存在则创建然后指向这个地址,如果存在直接指向。

下面我们来看一下享元模式的UML图



在就是上面案例的代码实现:

//抽象享元类,例子是车
interface Car{
void getCar();
}
//具体享元类,例子是跑车
class Roadster implements Car{
private String color;
public Roadster(String color){
this.color=color;
}
@Override
public void getCar() {
System.out.println("获得一辆"+color+"跑车");
}
}
//享元工厂类
class CarFactory{
public static  Map map=new HashMap();
public static Car getACar(String color){
//判断有无同颜色的车
if(!map.containsKey(color)){
map.put(color, new Roadster(color));
}
return (Car)map.get(color);
}
public static int getKind(){
return map.size();
}
}
public class Client {
public static void main(String[] args) {
Car car1=CarFactory.getACar("黄色");
car1.getCar();
Car car2=CarFactory.getACar("黄色");
car2.getCar();
Car car3=CarFactory.getACar("蓝色");
car3.getCar();
Car car4=CarFactory.getACar("红色");
car4.getCar();
System.out.println("一共获得"+CarFactory.getKind()+"种颜色跑车");
}
}


输出是

获得一辆黄色跑车

获得一辆黄色跑车

获得一辆蓝色跑车

获得一辆红色跑车

一共获得3种颜色跑车

很明显可以看出,不用创建很多实例了。

享元模式的优点是:

可以减少很多相似对象,减少系统的内存消耗。

使用了内外部的模式且相对的比较独立,所以享元对象能够在不同的坏境中被共享。

至于适用范围,不说也很清楚啦,只要能发挥它优势的地方都可以使用,也就是说一个系统中存在大量相似或相同对象的时候就可以使用了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息