注意:阅读本文时,强烈建议先阅读下 OneMall 项目的概要设计
由于我们需要对接各大商城的 API,所以我们需要在 Supplier 模块实现各大商城的 API client,提供一个 client 供其他模块来调用。每个商城的 API client 只需要一个就可以了。这个 client 就可以使用单例模式。
代码实现:
public class JdApiSingleton {
private static final JdApiSingleton self = new JdApiSingleton();
private JdApiSingleton() {
}
public static JdApiSingleton getJdApi() {
return self;
}
/**
* 获取商品信息
*
* @param url 地址
* @param param 参数
* @return 商品实体
*/
public static GoodsDTO getGoodsInfo(String url, Map<String, Object> param) {
String result = HttpClientUtil.get(url, param);
return JSONObject.parseObject(result, GoodsDTO.class);
}
/**
* 提交订单
*
* @param url 地址
* @param param 参数
* @return 订单信息
*/
public static OrderDTO submitOrder(String url, Map<String, Object> param) {
String result = HttpClientUtil.post(url, param);
return JSONObject.parseObject(result, OrderDTO.class);
}
}
单例模式比较简单,这里使用了”饿汉式”的设计,私有化构造方法,确保应用中只有一个实例,然后还有提供了其他各种 API,用于实现业务逻辑。
单例模式的类图比较简单,只需要一个 Singleton 就可以实现单例模式。单例模式不仅仅只有一种实现方式,上面这种“饿汉式”式最简单的实现。有兴趣的可以说搜一下其他的实现方式,由于本文讨论的是设计模式,这里不再详细讨论别的实现方式。
在内存中产生一个实例很简单,但是,在有些情况下我们可能需要固定数量的实例,用来提高应用的性能。比如在多线程的情况下,我们可能需要为每个线程分配一个实例。这个时候我们就可以在内存中生成固定数量的实例,数量与线程池的大小保持一致。
代码实现:
public class JdApiSingletonPool {
//实例最大个数
private static final int MAX_NUM = 4;
private static final List<JdApiSingletonPool> pool = new ArrayList<>(MAX_NUM);
private JdApiSingletonPool() {
}
//初始化单例池
static {
for (int i = 0; i < MAX_NUM; i++) {
pool.add(new JdApiSingletonPool());
}
}
/**
* 获取实例
*
* @param index 下标
* @return 如果下标越界返回 null
*/
public static JdApiSingletonPool getJdApiSingleton(int index) {
if (index < 0 || index >= MAX_NUM) {
return null;
}
return pool.get(index);
}
// other api ...
}
我们通过初始化一个单例的集合来存储所有的单例。这样就能够保证内存中有固定数量的单例实例。
单例模式(Singleton Pattern): 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
这个定义有 3 个含义:
单例模式的优点:
单例模式的缺点: