1.前言
享元模式是对象池的一种实现。用来尽可能减少内存使用量。可以共享的状态称为内部状态,内部状态不会随着环境变化而变化;不可共享的状态则称之为外部状态,随着环境的改变而改变。享元模式中会创建一个容器对象。比如Map。
2.定义
享元模式(Flyweight):运用共享技术有效地支持大量细粒度对象。
3.UML图
4.使用场景
(1)系统中存在大量的相似对象;
(2)细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定的身份;
(3)需要用到缓冲池
5.原理
享元模式通过消息池的形式有效的减少了重复对象的存在。它通过内部状态标识某个种类的对象,外部程序根据这个不会变化的内部状态从消息池中取出对象。使得同一类对象可以被反复用,避免大量重复对象。
看一个例子:
//展示车票信息的
public interface Ticket {
void showTicketInfo(String bunk);
}
public class TrainTicket implements Ticket {
private String destination;
private String start;
private String bunk;//铺位
private int price;
public TrainTicket(String destination, String start) {
this.destination = destination;
this.start = start;
}
@Override
public void showTicketInfo(String bunk) {
price = new Random().nextInt(200);
Log.d("zsf", "火车票从" + start + "到" + destination + "的" + bunk + "的价格是:" + price);
}
}
public class TicketFactory {
public static Ticket getTicket(String start,String destination){
//每次都会new一个TrainTicket对象
return new TrainTicket(destination,start);
}
}
上面的这几段代码中在最后的TicketFactory中return的TrainTicket就是会重复创建对象。如何修改?使用享元模式。
public class TicketFactory {
static Map<String,Ticket> sTicketMap = new ConcurrentHashMap<>();
public static Ticket getTicket(String start,String destination){
String key = start + "-" + destination;
if (sTicketMap.containsKey(key)){
//使用缓存
return sTicketMap.get(key);
}else {
//创建对象
Ticket ticket = new TrainTicket(destination,start);
sTicketMap.put(key,ticket);
return ticket;
}
}
}
内部状态就是出发地和目的地;外部状态就是位置和价格。