享元模式

享元模式

一、简介

享元模式是对象池的一种实现,它用来尽可能减少内存使用量,适合可能存在大量重复对象的场景,缓存可共享的对象避免创建过多对象。

享元对象中的部分状态是可共享称之为内部状态,内部状态不会随环境变化。不可共享的状态称之为外部状态,会随环境改变而变化。在享元模式中建立一个对象容器它的键是享元对象的内部状态,值是享元对象本身。客户端通过内部状态从享元工厂中获取享元对象,如果有缓存则直接返回缓存否则创建新对象存入容器中然后返回。

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

二、使用场景

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

三、简单实现

以查询火车票信息为例,我们在查询某辆火车的车票时会向服务端发送请求,这里的“请求”如果每到一个服务端就创建一个新的使用完成后销毁,这样做会使得大量重复对象创建销毁频繁GC。如果把请求缓存起来则会减少很多内存占用。

    public interface Ticket{
        void showTicketInfo();
    }

    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;
        }

        @Override
        public void showTicketInfo() {
            price=new Random().nextInt(100);
            Log.i(TAG, "showTicketInfo: form "+from+" to "+to+" bunk "+bunk+"  price "+price);
        }
    }
    
    public class TicketFactory{
     Map<String,Ticket> map=new ConcurrentHashMap<>();
        
     public  Ticket getTicket(String form,String to){
         String key=form+"-"+to;
         if (map.containsKey(key)){
             Log.i(TAG, "getTicket: cached");
             return map.get(key);
         }else {
             Log.i(TAG, "getTicket: create");
             Ticket ticket=new TrainTicket(form,to);
             map.put(key,ticket);
             return ticket;
         }
     }
        
    }
    
    public void Test(){
        TicketFactory ticketFactory=new TicketFactory();
        Ticket ticket1=ticketFactory.getTicket("北京","天津");
        ticket1.showTicketInfo();

        Ticket ticket2=ticketFactory.getTicket("北京","天津");
        ticket2.showTicketInfo();

        Ticket ticket3=ticketFactory.getTicket("北京","天津");
        ticket3.showTicketInfo();
    }

四、小结

在Android中Handler机制中使用的Message内部就采用了享元模式,Message内部有一个消息缓存池当我们需要一个Message时可以通过Message.obtain来获取一个Message。当缓冲池为空时则会创建Message然后当Message不在使用时回收至缓冲池中。

享元模式可以大大减少对象的创建,降低内存占用,但是它需要分离出外部状态和内部状态,且外部状态具有固话特性。

该模式的优势就是大幅降低内存中对象的数量,但是相对应的它使系统更加复杂。

posted @ 2020-10-14 18:54  Robin132929  阅读(13)  评论(0编辑  收藏