我们都知道,Java中的String类具有如下特性:String是一个不可变类,当直通过用字符串方式使用String对象时,Jvm实际上在内存中只存有一份,且存在字符串常量池中。当对字符串直接进行修改时(如直接联接另一个字符串常量),Jvm会首先去字符串常量池中查找是否已经存在此字符串,不存在则创建一份放在池中,存在则直接使用。诸如此类:当系统中可能具有多个相同的对象时,对于具有相同的内容的对象可以实现对象的共享,即共享池,以此避免不必要的相同对象的创建以减少系统内存的开销。称之为享元模式。
对于定义中的相同的对象,相同一词如何理解?首先我们需要解释下享元模式中的两个概念:内蕴状态和外蕴状态。
内蕴状态:享元对象内部的可以以此来作为区分是否是同一个对象的依据的属性。内蕴状态不随着外部环境的变化而变化。
外蕴模式:虽然也是享元对象的属性,但可以随着外部环境的变换而变化,同一享元对象在不同的地方其内部的外蕴状态可能不同。
享元模式一般的累定义过程如下:
1. 定义享元类的接口:
interface Flyweight{ // 用于改变外蕴状态
public void changeStat(String exState); }
2.定义发具体的享元类:
class ConcreteFlyweight implements Flyweight { //内蕴状态
private String innerState; // 外蕴状态
private String exState; public ConcreteFlyweight(String innerState) {
this.innerState = innerState;
} @Override
public void changeStat(String exState) {
this.exState = exState;
} }
3. 定义工厂类,用来管理享元对象:
class FlyweightFactory {
private static Map<String, Flyweight> flyweightMap = new HashMap<String, Flyweight>(); public static Flyweight getFlyweight(String innerState) {
Flyweight flyweight = flyweightMap.get(innerState);
if (flyweight == null) {
flyweight = new ConcreteFlyweight(innerState);
flyweightMap.put(innerState, flyweight);
}
return flyweight;
} }
4. 客户端测试:
public class FlyweightTest { public static void main(String[] args) {
Flyweight a = FlyweightFactory.getFlyweight("A");
a.changeStat("first-A");
Flyweight b = FlyweightFactory.getFlyweight("B");
b.changeStat("first-B");
Flyweight aa = FlyweightFactory.getFlyweight("A"); a.changeStat("second-A");
Flyweight bb = FlyweightFactory.getFlyweight("B");
b.changeStat("second-B"); System.out.println(a == aa); // true
System.out.println(b == bb); // true
}
}
通过最近的7篇文章大体上对Java设计模式中的七中结构型模式进行了总结,分别是:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式和享元模式。