设计模式

设计模式-享元模式

2020-05-23  本文已影响0人  isLJli

享元设计模式的定义:

使共享对象可有效的支持大量的细粒度的对象,核心就是对象复用。

对象的复用,比较常用两种方法是:一:根据HashMap进行对象的复用,二:根据对象池进行复用。

享元设计模式的举例

返回购票的价格对象
在做高铁火车时,不同的路段返回不同的价格,但是相同的路段的价格是一样的,我们就可以为查询相同路径的人共同返回一个价格的复用对象,不用每次都创建一个新的对象.。使用hashMap的方法。
1.创建返回价格的对象

public class Ticket {
  String from;
  String to;
  int getPirce(){
      return new Random().nextInt(100)+20;
  }

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

2。利用工厂模式创建不同的价格对象
用hashMap存储不同的路径的价格对象

public class TicketFactory {

  static Map<String, Ticket> sTicketMap = new HashMap<>();

  public static Ticket getTicket(String form, String to) {
      String key = form + "-" + to;
      Ticket ticket = sTicketMap.get(key);
      if (ticket != null) {
          return ticket;
      }
      
      ticket = new Ticket(form, to);
      sTicketMap.put(key, ticket);
      return ticket;
  }
}

3.客户端的请求

public static void main(String[] argss){
      for (int i= 0;i<1000;i++){
          Ticket ticket = TicketFactory.getTicket("深圳","北京");
      }
  }

Message的对象复用

在Handler发送消息时我们会用到Message对象来发送消息。
我们一般会使用第二种,复用对象的创建方式:

Message message = new Message();
Message message1 = Message.obtain();

来看看Message.obtain()是怎样对象复用的?

// Message是一个有next的链表组成,sPool 就是复用的Message链表
public static Message obtain() {
      synchronized (sPoolSync) {
          if (sPool != null) {
              Message m = sPool; //拿到第一个msg
              sPool = m.next;  //将sPool 移到第二个msg
              m.next = null; //将第一个的msg的next制空
              m.flags = 0; // clear in-use flag
              sPoolSize--; //复用对象大小-1
              return m;  //返回第一个复用对象
          }
      }
      return new Message(); //否则创建新的msg
  }

那看看Message又是怎么回收的

void recycleUnchecked() {
      // Mark the message as in use while it remains in the recycled object pool.
      // Clear out all other details.
      flags = FLAG_IN_USE;
      what = 0;
      arg1 = 0;
      arg2 = 0;
      obj = null;
      replyTo = null;
      sendingUid = UID_NONE;
      workSourceUid = UID_NONE;
      when = 0;
      target = null;
      callback = null;
      data = null;

      synchronized (sPoolSync) {
          if (sPoolSize < MAX_POOL_SIZE) {
              next = sPool; //将要回收的Msg的next变成sPool
              sPool = this; //sPool 移动到第一个msg
              sPoolSize++;//大小+1
          }
      }
  }

LayoutInflater创建控件时,也会复用控件的构造参数对象

上一篇下一篇

猜你喜欢

热点阅读