享元模式

对象共享、避免创建多对象-享元模式

定义

使用共享对象可有效的支持大量的细粒度的对象

使用场景

  1. 系统中存在大量的相似对象
  2. 细粒度的对象都具备接近的外部形态,而且内部状态与环境无关,也就是说对象没有特定身份
  3. 需要缓冲池的场景

简单实现

车票工厂:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package XiangyuanMode;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

//车票工厂,以出发地和目的地为key缓存车票
public class TicketFactory {
    static Map<String,Ticket> sTicketMap=new ConcurrentHashMap<String, Ticket>();
    public static Ticket getTicket(String from,String to){
        String key=from+"-"+to;
        if(sTicketMap.containsKey(key)){
            System.out.println("使用缓存==>"+key);
            return sTicketMap.get(key);
        }else{
            System.out.println("创建对象==>"+key);
            Ticket ticket=new TrainTicket(from,to);
            sTicketMap.put(key, ticket);
            return ticket;
        }
    }
}

实体类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package XiangyuanMode;


import java.util.Random;

public class TrainTicket implements Ticket {
    public String from;//出发地
    public String to;//目的地
    public String bunk;//铺位
    public int price;

    public TrainTicket(String from, String to) {
        this.from = from;
        this.to = to;
    }

    public void showTicketInfo(String bunk) {
        price=new Random().nextInt(300);
        System.out.println("购买 从"+from+"到"+to+"的"+bunk+"火车票,价格:"+price);
    }
}

接口类

1
2
3
4
5
package XiangyuanMode;

public interface Ticket {
    public void showTicketInfo(String bunk);
}

测试类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package XiangyuanMode;

public class Test {
    public static void main(String[] args) {
        Ticket ticket1=TicketFactory.getTicket("北京","青岛");
        ticket1.showTicketInfo("上铺");
        Ticket ticket2=TicketFactory.getTicket("北京","青岛");
        ticket2.showTicketInfo("中铺");
        Ticket ticket3=TicketFactory.getTicket("北京","青岛");
        ticket3.showTicketInfo("下铺");
    }
}

输出结果

222.png

总结

优点

  • 大幅降低了内存中对象的数量

缺点:

  • 使系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
  • 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长