如何在对外接口中合理地使用枚举

首先贴出阿里java开发手册华山版第39页的一句话
【强制】 二方库里可以定义枚举类型,参数可以使用枚举类型,但是接口返回值不允许使用
枚举类型或者包含枚举类型的 POJO 对象

关于这句话,讲一个业务场景:近期因业务发展,我们的一个系统需要增加一个枚举值,而某个接口的返回值直接使用了这个枚举。于是需要通知上游接口同步升级jar包,联调,上线。试想,如果这个枚举被10个接口使用,每个接口有10个上游系统调用,全部需要升级jar包上线;如果有20个接口…

于是我们目前采用了一种策略,在枚举类里提供根据code获取枚举的方法,并在接口回传参数时,只回传code,且允许null;上游接口使用时需要通过code获取枚举,可以直接使用枚举的name,也可以通过switch分支自定义name

package com.example.demo.guava;

import lombok.Getter;
import lombok.ToString;

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

/**
 * description
 *
 * @author xichengxml
 * @date @date 2019-10-30 10:57:59
 */
@Getter
@ToString
public enum GenderEnum {

	MALE("M", "男"),
	FEMALE("F", "女");

	private String code;

	private String name;

	private final static Map<String, GenderEnum> container;

	static {
		container = new HashMap<>();
		for(GenderEnum e : GenderEnum.values()) {
			container.put(e.getCode(), e);
		}
	}

	/**
	* 内部使用
	*/
	public static GenderEnum getEnum(String code) {
		return getEnum(code, false);
	}
	
	/**
	* 提供给外部使用
	*/
	public static GenderEnum getEnum(String code, boolean allowNull) {
		GenderEnum e = container.get(code);
		if (e == null && !allowNull) {
			throw new IllegalArgumentException("no enums code '" + code + "'. ");
		}
		return e;
	}
	
	GenderEnum(String code, String name) {
		this.code = code;
		this.name = name;
	}
}

package com.example.demo;

import com.example.demo.guava.GenderEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.junit.Test;

/**
 * description
 *
 * @author xichengxml
 * @date 2019-10-30 11:02:24
 */
public class EnumTest {

	@Test
	public void test01() {
		// 上游接口调用下游业务接口返回
		Person person = getPerson();
		// 获取下游业务接口返回数据
		String genderCode = person.getGenderCode();
		GenderEnum genderEnum = GenderEnum.getEnum(genderCode, true);
		// 上游系统封装自己的实体类
		PageView pageView = new PageView();
		pageView.setUname(person.getUname());
		pageView.setGender(genderEnum.getName());
		System.out.println("response with enum: " + pageView);
	}

	/**
	 * 模拟下游业务接口实现
	 * 业务方法直接封装enum code
	 * @return
	 */
	private Person getPerson() {
		Person person = new Person();
		person.genderCode = GenderEnum.MALE.getCode();
		person.uname = "xicheng";
		return person;
	}

	/**
	* 模拟下游业务代码实体类
	*/
	@Getter
	@Setter
	private static class Person {
		private String uname;
		private String genderCode;
	}

	/**
	* 用于上游系统返回页面的实体
	*/
	@Getter
	@Setter
	@ToString
	private static class PageView {
		private String uname;
		private String gender;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章