一. 定义
当系统中存在大量相同或者相似的对象时,享元模式通过共享技术实现相同或者相似的细粒度对象的复用,从而节约了内存空间。
二. 模式结构

1. Flyweight(抽象享元类)
声明一个接口,通过它可以接受并作用于外部状态。在抽象享元类中定义了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据,同时也可以通过这些方法设置外部数据。
2. ConcreteFlyweight(具体享元类)
实现了抽象享元接口,其实例为享元对象。在具体享元类中为内部数据提供了存储空间,由于具体享元对象必须是可以共享的,因此它所存储的状态必须独立存在于自己的环境中。
3. UnsharedConcreteFlyweight(非共享具体享元类)
不需要共享的具体享元类
4. FlyweightFactory(享元工厂类)
用于创建和管理享元对象。针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中,一般是键值对。
三. 实例

1. NetworkDevice(抽象享元类)
public interface NetworkDevice {
    public String getType();
    public void use();
}2. Switch
public class Switch implements NetworkDevice {
    private String type;
    public Switch(String type) {
        this.type = type;
    }
    @Override
    public String getType() {
        return this.type;
    }
    @Override
    public void use() {
        System.out.println("SWITCH链接中,类型为:"+this.type);
    }
}3. Hub
public class Hub implements NetworkDevice{
    private String type;
    public Hub(String type) {
        this.type = type;
    }
    @Override
    public String getType() {
        return this.type;
    }
    @Override
    public void use() {
        System.out.println("hub链接中,类型为:"+this.type);
    }
}4. DeviceFactory(享元工厂)
import java.util.ArrayList;
public class DeviceFactory {
    private ArrayList devices=new ArrayList();
    private int totalTerminal=0;
    public DeviceFactory() {
        NetworkDevice Nd1=new Switch("1");
        devices.add(Nd1);
        NetworkDevice nd2=new Hub("2");
        devices.add(nd2);
    }
    public NetworkDevice getNetworkDevice(String type)
    {
        if(type.equals("1"))
        {
            totalTerminal++;
            return (NetworkDevice) devices.get(0);
        }
        else if(type.equals("2"))
        {
            totalTerminal++;
            return (NetworkDevice) devices.get(1);
        }
        else{
            return null;
        }
    }
    public int getTotalDevice()
    {
        return devices.size();
    }
    public int getTotalTerminal()
    {
        return totalTerminal;
    }
}5. Client
public class Client
{
    public static void main(String[] args) throws Exception
    {
        NetworkDevice n1, n2, n3, n4;
        DeviceFactory df=new DeviceFactory();
        n1=df.getNetworkDevice("1");
        n1.use();
        n2= df.getNetworkDevice("1");
        n2.use();
        n3= df.getNetworkDevice("2");
        n3.use();
        n4= df.getNetworkDevice("2");
        n4.use();
        System.out.println("Total Device "+df.getTotalDevice());
        System.out.println("Total Terminal "+df.getTotalTerminal());
    }
}