一、简介
1.1 模式定义
运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
1.2 适用场景
1)一个系统有大量相同或者相似的对象,由于这类对象额大量使用,造成内存的大量耗费。
2)对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
3)使用享元模式须要维护一个存储享元对象时才值得使用享元模式。
1.3 优点
1)享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
2)享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
1.4 缺点
1)享元模式使得系统更加复杂,须要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
2)为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间边长。
二、示例
2.1 结构图
2.2 抽象享元类NetworkDevice (网络设备类)
public interface NetworkDevice {
public String getType();
public void use(Port port);
}
2.3 具体享元类Switch(交换机类)
public class Switch implements NetworkDevice{
private String type;
public Switch(String type) {
this.type = type;
}
@Override
public String getType() {
return type;
}
@Override
public void use(Port port) {
System.out.println("Linked by switch, type is " + type + ",port is " + port.getPort());
}
}
2.4 具体享元类Hub(集线器类)
public class Hub implements NetworkDevice{
private String type;
public Hub(String type) {
this.type = type;
}
@Override
public String getType() {
return type;
}
@Override
public void use(Port port) {
System.out.println("Linked by hub, type is " + type + ",port is " + port.getPort());
}
}
2.5 属性类Port
public class Port {
private String port;
public Port(String port) {
this.port = port;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
}
2.6 享元工厂类DeviceFactory (网络设备工厂类)
public class DeviceFactory {
private List<NetworkDevice> devices = new ArrayList<>(); // 享元池
private int totalTerminal = 0;
public DeviceFactory() {
NetworkDevice nd1 = new Switch("Cisc0-WS-C2950-24");
devices.add(nd1);
NetworkDevice nd2 = new Hub("TP-LINK-HF8M");
devices.add(nd2);
}
public NetworkDevice getNetworkDevice(String type) {
if (type.equalsIgnoreCase("cisco")) {
totalTerminal++;
return devices.get(0);
} else if (type.equalsIgnoreCase("tp")) {
totalTerminal++;
return devices.get(1);
} else {
return null;
}
}
public int getTotalDevice() {
return devices.size();
}
public int getTotalTerminal() {
return totalTerminal;
}
}