系统中对象数目太多,有些对象是相同或是相似的,享元模式就是实现对象复用。
一个文本文档中有大量的字符串,如果每个字符串都用一个单独对象来表示,那么整个的运行开销太大了,享元模式就是解决这样的问题,逻辑上每个出现的字符串都有一个对象与之对应,然而在物理上他们共享同一个享元对象,这个对象可以出现在同一个文档的不同地方,相同的字符串对象指向同一个实例,储存这个实例的对象可以称为享元池。
享元模式组成:抽象享元类,具体享元类, 非共享具体享元类,享元工厂类。
享元模式的核心在享元工厂类,享元工厂作用是在于提供一个用于储存对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象并返回给用户,并在享元池中保存该新增对象。(是不是很像常量池)。
//共享网络设备(无外部状态)
//抽象共享元
public interface NetworkDevice {
public String getType();
public void use();
}
//具体享元类
public class Hub implements NetworkDevice {
private String type;
public Hub(String type){
this.type = type;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return this.type;
}
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("Linked by Hub,type is" + this.type);
}
}
public class Switch implements NetworkDevice {
private String type;
public Switch(String type){
this.type = type;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return this.type;
}
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("Linked by switch,type is" + this.type);
}
}
//享元工厂
import java.util.ArrayList;
public class DeviceFactory {
private ArrayList<NetworkDevice> devices = new ArrayList<NetworkDevice>();
private int totalTerminal = 0;
public DeviceFactory(){
NetworkDevice nd1 = new Switch("Cisco-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 (NetworkDevice)devices.get(0);
}
else if(type.equalsIgnoreCase("tp")){
totalTerminal ++;
return (NetworkDevice)devices.get(1);
}
else {
return null;
}
}
public int getTotalDevice(){
return devices.size();
}
public int getTotalTerminal(){
return totalTerminal;
}
}
//有外部区别
public interface NetworkDevice {
public String getType();
public void use(Port port);
}
public class Port {
public String port;
public Port(String port){
this.port = port;
}
public String getPort(){
return this.port;
}
public void setPort(String port){
this.port = port;
}
}
public class Switch implements NetworkDevice {
private String type;
public Switch(String type){
this.type = type;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return this.type;
}
public void use(Port port){
System.out.println("Linked by switch type is" + this.type + ",port is" + port.getPort());
}
}
public class Hub implements NetworkDevice {
private String type;
public Hub(String type){
this.type = type;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return this.type;
}
@Override
public void use(Port port) {
// TODO Auto-generated method stub
System.out.println("Linked by Hub type is" + this.type +",port is" + port.getPort());
}
}
public class DeviceFactory {
private ArrayList<NetworkDevice> devices = new ArrayList<NetworkDevice>();
private int totalTerminal = 0;
public DeviceFactory(){
NetworkDevice nd1 = new Switch("Cisco-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 (NetworkDevice)devices.get(0);
}
else if(type.equalsIgnoreCase("tp")){
totalTerminal ++;
return (NetworkDevice)devices.get(1);
}
else {
return null;
}
}
public int getTotalDevice(){
return devices.size();
}
public int getTotalTerminal(){
return totalTerminal;
}
}
//在外部调用的时候,port是不一样的,但是对象相同
享元模式跟单例模式是不一样的,享元模式面对的是一群对象,而单例模式是一个对象。
享元模式优点:
(1)它可以极大的减少内存中对象的数量,使得相同的对象或相似的对象在内存中只有一份。
享元模式适用的地方:
(1)一个系统中有大量相同或者相似的对象,由于这类对象的大量使用,造成内存大量耗费。