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