设计模式-享元模式(flyweight)以及在JDK类库中的应用

享元模式是一种用于性能优化的设计模式,通过共享技术减少大量相似对象的创建。在Java中,Integer、Boolean等类的valueOf方法就实现了享元模式,如Integer在-128到127之间会复用已有对象。这种模式可以降低内存开销,但也会增加系统复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

享元模式

定义

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

结构

FlyWeight:抽象享元类,它定义了具体享元类实现的接口。

ConcreteFlyWeight:具体享元类, 为内部状态增加存储空间。

FlyWeightFactory:享元工厂类,核心是HashMap或者HashTable,工厂类初始化时将享元对象put到集合中,根据客户端提供的标识来返回指定的享元对象。

UnsharedConcreteFlyWeight:非共享的对象。

类图

享元工厂类:

public class FlyWeightFactory {

	private Hashtable<String, FlyWeight> factory = new Hashtable<String, FlyWeight>();
	
	public FlyWeightFactory(){
		factory.put("X", new ConcreteFlyWeight());
		factory.put("Y", new ConcreteFlyWeight());
		factory.put("Z", new ConcreteFlyWeight());
	}

	public Hashtable<String, FlyWeight> getFactory() {
		return factory;
	}

	public void setFactory(Hashtable<String, FlyWeight> factory) {
		this.factory = factory;
	}

}

抽象享元类:

public abstract class FlyWeight {
	public abstract void operation(int n);
}

具体享元类:

public class ConcreteFlyWeight extends FlyWeight{

	@Override
	public void operation(int n) {
		System.out.println("具体的flyWeight:"+n);
	}

}

非共享对象:

public class UnsharedConcreteFlyWeight extends FlyWeight{

	@Override
	public void operation(int n) {
		System.out.println("不共享的具体FlyWeight:"+n);
	}
	
}

测试类

	
	public static void main(String[] args) {
		int n = 10;
		FlyWeightFactory flyWeightFactory = new FlyWeightFactory();
		FlyWeight flyWeight1 = flyWeightFactory.getFactory().get("X");
		FlyWeight flyWeight2 = flyWeightFactory.getFactory().get("X");
		FlyWeight flyWeight3 = flyWeightFactory.getFactory().get("X");
		UnsharedConcreteFlyWeight unsharedConcreteFlyWeight = new UnsharedConcreteFlyWeight();
		flyWeight1.operation(--n);
		flyWeight2.operation(--n);
		flyWeight3.operation(--n);
		unsharedConcreteFlyWeight.operation(--n);
	}
	

测试结果:

优点

大大减少重复对象的生成,减少了内存开销,提高性能。

缺点

增加系统的复杂度,外部状态随环境的改变而改变,而内部状态不会改变。

JDK类库中的享元模式

java.lang.Integer#valueOf(int) 

java.lang.Boolean#valueOf(boolean) 

java.lang.Byte#valueOf(byte) 

java.lang.Character#valueOf(char)

java.lang.Long#valueOf(long)

我们都知道Integer有一个初始化值默认范围(-128到127),如果在这个范围内Integer.valueOf(n)这个方法返回缓存中的值,否则创建一个新的Integer对象。源码如下:

    /**
     * Returns a <tt>Integer</tt> instance representing the specified
     * <tt>int</tt> value.
     * If a new <tt>Integer</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Integer(int)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  i an <code>int</code> value.
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
	final int offset = 128;
	if (i >= -128 && i <= 127) { // must cache 
	    return IntegerCache.cache[i + offset];
	}
        return new Integer(i);
    }

Boolean类中初始化了两个静态常量TRUE、FALSE:

    /** 
     * The <code>Boolean</code> object corresponding to the primitive 
     * value <code>true</code>. 
     */
    public static final Boolean TRUE = new Boolean(true);

    /** 
     * The <code>Boolean</code> object corresponding to the primitive 
     * value <code>false</code>. 
     */
    public static final Boolean FALSE = new Boolean(false);

调用Boolean.valueOf(b)将会根据参数b返回实现缓存的常量。

Byte的valueOf方法和Integer同理,都是返回缓存中的值。

    /**
     * Returns a <tt>Byte</tt> instance representing the specified
     * <tt>byte</tt> value.
     * If a new <tt>Byte</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Byte(byte)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  b a byte value.
     * @return a <tt>Byte</tt> instance representing <tt>b</tt>.
     * @since  1.5
     */
    public static Byte valueOf(byte b) {
	final int offset = 128;
	return ByteCache.cache[(int)b + offset];
    }

Character值的默认范围是小于127,如果小于127,则返回缓存中的值,否则创建新的Character对象。

    /**
     * Returns a <tt>Character</tt> instance representing the specified
     * <tt>char</tt> value.
     * If a new <tt>Character</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Character(char)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  c a char value.
     * @return a <tt>Character</tt> instance representing <tt>c</tt>.
     * @since  1.5
     */
    public static Character valueOf(char c) {
	if(c <= 127) { // must cache
	    return CharacterCache.cache[(int)c];
	}
        return new Character(c);
    }

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值