Android设计模式

Android设计模式-21-享元模式

2018-06-20  本文已影响50人  今阳说

1. 定义

2. 使用场景

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

3. 优缺点

4. Android源码中的使用

我们平时使用的Handler中的getPostMessage所得到的message对象就是通过享元模式创建的, 可以看下如下代码:

  //使用Handler
  handler.post(new Runnable() {
     @Override
     public void run() {
         mTextViewShow.append("\nThread中new Handler(Looper.getMainLooper()) 更新UI");
     }
  });
  //源码:
  public final boolean post(Runnable r) {
        return sendMessageDelayed(getPostMessage(r), 0);
    }

    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }

    // 可以看到Message对象并不是通过new去大量构建的,而是通过一个默认大小为50的对象池
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

5. 实例演示

以购买火车票为例

  1. 创建一个车票接口
  public interface Ticket {
        //展示车票信息的函数
        void showTicketInfo(String bunk);
    }
  1. 创建一个实现类-火车票
  //火车票
    public static 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(String bunk) {
            this.bunk = bunk;
            price = new Random().nextInt(500);
            LjyLogUtil.i("购买 从 " + from + " 到 " + to + " 的 " + bunk + " " +
                    "火车票" + ", 价格: " + price);
        }

    }
  1. 创建车票的工厂类,使用享元模式
  public static class TicketFactory {
        static Map<String, Ticket> sTicketMap = new HashMap<>();

        public static Ticket getTicket(String from, String to) {
            //1.普通写法: 每次都new会消耗资源和内存,甚至导致OOM
//            return new TrainTicket(from, to);
            //2.享元模式
            String key = from + "-" + to;
            if (sTicketMap.containsKey(key)) {
                LjyLogUtil.i("使用缓存==> " + key);
                return sTicketMap.get(key);
            } else {
                LjyLogUtil.i("创建对象==> " + key);
                Ticket ticket = new TrainTicket(from, to);
                sTicketMap.put(key, ticket);
                return ticket;
            }

        }
    }
  1. 使用享元创建实例
  private void methodFlyweightPattern() {
        //以购买火车票为例
        Ticket ticket1 = TicketFactory.getTicket("北京", "廊坊");
        ticket1.showTicketInfo("软座");
        Ticket ticket2 = TicketFactory.getTicket("北京", "云南");
        ticket2.showTicketInfo("上铺");
        Ticket ticket3 = TicketFactory.getTicket("北京", "廊坊");
        ticket3.showTicketInfo("站票");
    }

上一篇 下一篇

猜你喜欢

热点阅读