一. 定义

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


二. 模式结构

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());
    }
}