声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635

FlyWeight模式即享元模式。很多文本编辑器中都使用了FlyWeight模式。FlyWeight单词含义为轻量级的。该模式主要是使得大量对象可以共享某些元素,从而减少内存使用。比如文本编辑器中每个文字都会有字体属性,如果给每个文字的字体属性都分配一个对象,那对内存的消耗就太大了。此时享元模式就派上用场了。享元模式也是一种具体的“池化”技术。

享元操作接口
package com.designpattern.flyweight;

/**
 * 字体享元接口
 */
public interface FontFlyWeight
{
    void setFont(String color, int size);

    void getFont();
}

具体享元
package com.designpattern.flyweight;

public class SharedConcreteFontFlyWeight implements FontFlyWeight
{
private String color;
private int size;
private String str;

public SharedConcreteFontFlyWeight(String str)
{
    this.str = str;
}

public void setFont(String color, int size)
{
    this.color = color;
    this.size = size;
}

public void getFont()
{
    System.out.println("str:" + str + ", color:" + color + ",size:" + size);
}

}

享元工厂

package com.designpattern.flyweight;

import java.util.Hashtable;

public class FontFactory
{
    //HashTable存放的就是可以复用的享元
    private Hashtable flyWeights = new Hashtable();

    public FontFlyWeight getFlyWeight(String str)
    {
        if (flyWeights.get(str) != null)
        {
            return (FontFlyWeight) flyWeights.get(str);
        }
        else
        {
            FontFlyWeight tmp = new SharedConcreteFontFlyWeight(str);
            flyWeights.put(str, tmp);
            return tmp;
        }
    }

    public Hashtable getFactory()
    {
        return flyWeights;
    }
}

测试类(客户端)

package com.designpattern.flyweight;

import java.util.Hashtable;

public class TestFlyWeight
{
public static void main(String[] args)
{
int[] size = {1, 2, 3, 4, 5};
String[] color = {“000000”, “111111”, “222222”, “333333”, “555555”};
FontFactory fontFactory = new FontFactory();
String str = “算法导论”;
int flyWeightIndex;
int flyWeightNum = color.length; //or size.length
for (int i = 0; i < str.length(); i++)
{
//这个规则是自己任意定的
flyWeightIndex = i / flyWeightNum;
fontFactory.getFlyWeight(str.substring(i, i + 1)).setFont(
color[flyWeightIndex], size[flyWeightIndex]);
}

    //打印出所有享元
    Hashtable flyWeights = fontFactory.getFactory();
    FontFlyWeight fontFlyWeight;
    for (int i = 0; i < str.length(); i++)
    {
        fontFlyWeight = (FontFlyWeight) flyWeights.get(str.substring(i, i + 1));
        fontFlyWeight.getFont();
        System.out.println(System.identityHashCode(fontFlyWeight));
    }

    //创建另一个文本对象,观察其对享元的复用
    System.out.println("\n测试享元复用");
    String str2 = "算法入门";
    for (int i = 0; i < str2.length(); i++)
    {
        //这个规则是自己任意定的
        flyWeightIndex = i / flyWeightNum;
        fontFactory.getFlyWeight(str2.substring(i, i + 1)).setFont(
                color[flyWeightIndex], size[flyWeightIndex]);
    }
    for (int i = 0; i < str2.length(); i++)
    {
        fontFlyWeight = (FontFlyWeight) flyWeights.get(str2.substring(i, i + 1));
        fontFlyWeight.getFont();
        System.out.println(System.identityHashCode(fontFlyWeight));
    }
}

}

运行结果

str:算, color:000000,size:1
356573597
str:法, color:000000,size:1
1735600054
str:导, color:000000,size:1
21685669
str:论, color:000000,size:1
2133927002

测试享元复用
str:算, color:000000,size:1
356573597
str:法, color:000000,size:1
1735600054
str:入, color:000000,size:1
1836019240
str:门, color:000000,size:1
325040804

可以看到,“算”、“法”两个文字对应的享元被复用了。节约了内存开销。