主管约谈下的享元模式

主管约谈

       主管叫我过去,说到:“小陈,春节快要到了,为了方便我们同事查询火车票的情况,你开发一个火车票查询系统吧”。我心想,这个系统对于我来说,那简直是太简单了。

我是我着手这个需求的开发了。

需求开发

需求开发完以后,有彩蛋,一定要坚持看下去。

这就是一个简单的查询系统,实例代码如下:

第一步:定义一个票接口。

package com.example.createproject;

/**
 * 票接口
 */
public interface Ticket {

    /**
     * 获取票信息接口
     */
    void showTicketInfo();

}
复制代码

第二步:定义火者票的实现类。

package com.example.createproject;

import android.util.Log;

import java.util.Random;

public class TrainTicket implements Ticket {

    private static final String TAG = TrainTicket.class.getSimpleName();
    private String from;
    private String to;
    private String price;
    private String puwei;//铺位

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

    @Override
    public void showTicketInfo() {
        price = new Random().nextInt() + "";
        Log.e(TAG, "购买了从 " + from + "到" + to + " 的火车票,票价:" + price);
    }
}
复制代码

第三步:定义火车票的管理类。

package com.example.createproject;

public class TrainTicketManager {

    public static TrainTicket getTicketInfo(String from, String to, String puwei) {
        return new TrainTicket(from, to, puwei);
    }

}
复制代码

第四步:用户去查询火车票信息。

TrainTicket ticketInfo = TrainTicketManager.getTicketInfo("深圳", "西安", "上铺");
复制代码

写实现了上面的功能以后,我交给了主管,希望得到主管的夸奖:效率高,查询快….

主管再次约谈

        主管叫我过去,说到:“小陈,这样的系统你也敢给我看,getTicketInfo方法每次都返回一个TrainTicket对象 ,假设我们的系统有1000万的人同时查询,那岂不是要创建1000万个对象,那公司的服务器岂不是要爆炸了?”,我听到以后,觉得不是服务器要爆炸了,而是我的头要爆炸了。主管看我一脸困惑,说到:“你可以采用享元设计模式重构优化一下”。

我很敏锐的捕捉到了关键字:享元设计模式。

主管告诉我说:在下面的情况下,你可以考虑享元设计模式。

享元设计模式的场景

1、当一个系统中存在大量相似的对象。

2、如果系统中需要设计缓冲池。

比如在车票查询系统中,会爆发大量的车票信息对象,而对于一辆车K5038来说,它的作座位是固定的个数,比如有500个,如果我们有500万次查询,如果有500万个车票对象产生,显然是不合理的,那么我们可以进行如下优化。

思考:Android系统中哪些地方会使用池的设计思想、也可以认为是缓存的设计思想?

1、图片框架中的三级缓存思想。将图片缓存在内存和本地中。

2、网络框架中使用的线程池思想。

3、自定义控件属性集合TypeArray底层也是用了池的思想,我们可以通过typeArray.recycle();来看到。

4、消息机制中Message的创建,查看源码,我们发现Message是通过Message.obtain()来获取的,但是Message消息池并没有使用Map,而是使用的是链表,当我们获取Message的时候,首先是从缓冲池中获取,如果缓存池中没有,则重新创建一个。

优化流程

针对上面的流程,我们可以进行简单优化。

package com.example.createproject;

import java.util.HashMap;
import java.util.Map;

public class TrainTicketManager {

    // 缓冲池的思想
    static Map<String, TrainTicket> map = new HashMap<>();

    public static TrainTicket getTicketInfo(String from, String to, String puwei) {
        // key值
        String key = from + "-" + to + "-" + puwei;
        // 如果缓存中有,那么就从缓存中去取
        // 如果缓存中没有,那么构造之后,放入缓存中
        if (map.containsKey(key)) {
            return map.get(key);
        } else {
            TrainTicket trainTicket = new TrainTicket(from, to, puwei);
            map.put(key, trainTicket);
            return trainTicket;
        }
    }
}
复制代码

享元模式是什么

通过上面的例子,我们可以看到享元模式有下面的特点:

1、享元模式内部维护着一个缓冲池,这个缓冲池可以使Map,可以使链表,可以使其他的数据接口,选择最合适的就好。

2、它的核心思想其实就是缓存思想。

3、利用享元模式创建的系统,可以避免创建过多的对象。

主管继续给我讲到,我们将上面的流程图示化

享元模式的UML类图

总结

1、享元模式是比较简单的,主要是利用缓存数据结构的使用,比如Map等。

2、可以大大减少创建对象的个数,降低程序内存的使用,增强程序的性能。

猜你喜欢

转载自juejin.im/post/7055242666748936229