您的位置:首页 > 其它

设计模式——享元模式

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

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

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

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

享元模式的实现:

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
性感的女人。
漂亮的女人。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: