策略模式-专治多个if
前言:
本文例子是调用百度人脸库接口修改,新增,修改,删除接口,没有用策略模式是写的三个if如下
@Autowired
private AuthService authService;
@GetMapping(value = "/old")
public String old(String state) {
if ("add".equals(state)) {
FaceAdd.add(authService.getAuth(), "153****7719", "123456", "98989897", "李四");
}
if ("update".equals(state)) {
FaceUpdate.faceUpdate(authService.getAuth(), "153****7719", "123456", "98989897", "李四");
}
if ("delete".equals(state)) {
FaceDelete.faceDelete(authService.getAuth(), "153****7719", "123456", "98989897");
}
return "succ";
}
新增修改删除的工具类
新增
/**
* 人脸注册
*/
public class FaceAdd {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String add(String accessToken, String image,String groupId,String userId,String user_info) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
try {
Map<String, Object> map = new HashMap<>();
map.put("image", image);
map.put("group_id", groupId);
map.put("user_id", userId);
map.put("user_info", user_info);
map.put("liveness_control", "LOW");
map.put("image_type", "URL");
map.put("quality_control", "LOW");
String param = GsonUtils.toJson(map);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
// String accessToken = "[调用鉴权接口获取的token]";
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println("新增:"+result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
修改
/**
* 人脸注册
*/
public class FaceUpdate {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String faceUpdate(String accessToken, String image,String groupId,String userId,String user_info) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/update";
try {
Map<String, Object> map = new HashMap<>();
map.put("image", image);
map.put("group_id", groupId);
map.put("user_id", userId);
map.put("image_type", "URL");
map.put("user_info", user_info);
map.put("liveness_control", "LOW");
map.put("quality_control", "LOW");
String param = GsonUtils.toJson(map);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
// String accessToken = "[调用鉴权接口获取的token]";
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println("更新:"+result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
删除
/**
* 人脸删除
*/
public class FaceDelete {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String faceDelete(String accessToken, String faceToken,String groupId,String userId) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/face/delete";
try {
Map<String, Object> map = new HashMap<>();
map.put("face_token", faceToken);
map.put("group_id", groupId);
map.put("user_id", userId);
String param = GsonUtils.toJson(map);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
// String accessToken = "[调用鉴权接口获取的token]";
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println("删除:"+result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
获取人脸的access_token
@Component
public class AuthService {
/**
* 获取权限token
*
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
@Autowired
private RedisService redisService;
public String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = "i9EGdUMVvI";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = "2TLdpLcdXn";
return getAuth(clientId, clientSecret);
}
/**
* 获取API访问token
* 该token有一定的有效期,需要自行管理,当失效时需重新获取.
*
* @param ak - 百度云官网获取的 API Key
* @param sk - 百度云官网获取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public String getAuth(String ak, String sk) {
Object object = redisService.get("baidu-token", ak + sk);
if (object != null) {
String access_token = object.toString();
return access_token;
}
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + ak
// 3. 官网获取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
// for (String key : map.keySet()) {
// System.err.println(key + "--->" + map.get(key));
// }
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
//System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
long expires_in = jsonObject.getLong("expires_in")/60;
if (StringUtils.isNotBlank(access_token)) {
redisService.set("baidu-token", ak + sk, access_token, expires_in);
return access_token;
}
} catch (Exception e) {
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
return null;
}
}
策略模式-建BaiduFaceService接口
public interface BaiduFaceService {
void operation(String phone, String schoolCode, String uid, String name);
}
写三个实现add/update/delete类实现BaiduFaceService,并实现InitializingBean初始化执行。
策略模式-新增实现类主要写新增的业务逻辑
@Service
public class BaiduFaceAddServiceImpl implements BaiduFaceService, InitializingBean {
@Autowired
private AuthService authService;
@Override
public void operation(String phone, String schoolCode, String uid, String name) {
FaceAdd.add(authService.getAuth(), phone, schoolCode, uid, name);
}
/**
* @auther leichunhong
* @desc 启动就执行 往静态工厂放数据
* @date 2020-09-22 19:20
* @param
* @return void
*/
@Override
public void afterPropertiesSet() throws Exception {
BaiduFaceFactory.registerBaiduFace(UtilEnumCode.ENUM_A_VSAFECODE.getCode(), this);
}
}
策略模式-修改实现类主要是实现修改的业务逻辑
@Service
public class BaiduFaceUpdateServiceImpl implements BaiduFaceService, InitializingBean {
@Autowired
private AuthService authService;
@Override
public void operation(String phone, String schoolCode, String uid, String name) {
FaceUpdate.faceUpdate(authService.getAuth(), phone, schoolCode, uid, name);
}
/**
* @auther leichunhong
* @desc 启动就执行 往静态工厂放数据
* @date 2020-09-22 19:20
* @param
* @return void
*/
@Override
public void afterPropertiesSet() throws Exception {
BaiduFaceFactory.registerBaiduFace(UtilEnumCode.ENUM_U_VSAFECODE.getCode(), this);
}
}
策略模式-删除实现类是要是删除的业务逻辑
@Service
public class BaiduFaceDeleteServiceImpl implements BaiduFaceService, InitializingBean {
@Autowired
private AuthService authService;
@Override
public void operation(String phone, String schoolCode, String uid, String name) {
FaceDelete.faceDelete(authService.getAuth(), phone, schoolCode, uid);
}
/**
* @auther leichunhong
* @desc 启动就执行 往静态工厂放数据
* @date 2020-09-22 19:20
* @param
* @return void
*/
@Override
public void afterPropertiesSet() throws Exception {
BaiduFaceFactory.registerBaiduFace(UtilEnumCode.ENUM_D_VSAFECODE.getCode(), this);
}
}
策略模式-静态工厂其实就是一个key,value结构 key是 add/update/delete。 value 是 上文的三个实现类。根据不同的key(add/update/delete) 取不同的实现类,调不同的方法。
/**
* 〈功能简述〉<br>
* 〈〉静态工厂报存 操作类型 和操作实现类
* 比如: add---> BaiduFaceAddServiceImpl
*
* @author leichunhong
* @create 2020-09-22
* @since 1.0.0
*/
public class BaiduFaceFactory {
private static Map<String, BaiduFaceService> baiduFaceMap = new HashMap<>();
private BaiduFaceFactory() {
}
private static final BaiduFaceService EMPTY = new EmptyBaiduFace();
/**
* @param
* @return cn.thinkjoy.springboot.rest.business.service.BaiduFaceService
* @auther leichunhong
* @desc 根据k获取对象
* @date 2020-09-22 19:23
*/
public static BaiduFaceService getBaiduFace(String state) {
BaiduFaceService result = baiduFaceMap.get(state);
return result == null ? EMPTY : result;
}
/**
* @param
* @return
* @auther leichunhong
* @desc 初始化将对象注册到这里
* @date 2020-09-22 19:22
*/
public static void registerBaiduFace(String state, BaiduFaceService o) {
baiduFaceMap.put(state, o);
}
/**
* @param
* @auther leichunhong
* @desc 空对象
* @date 2020-09-22 19:22
* @return
*/
private static class EmptyBaiduFace implements BaiduFaceService {
@Override
public void operation(String phone, String schoolCode, String uid, String name) {
// Empty class
}
}
}
key的枚举工具类
public enum UtilEnumCode {
ENUM_A_VSAFECODE("A", "add"),
ENUM_U_VSAFECODE("U", "update"),
ENUM_D_VSAFECODE("D", "delete"),
SCHOOL_PRO_TYPE("test","test");
/** The code. */
private final String code;
/** The message. */
private final String message;
/**
* Instantiates a new error type.
*
* @param code
* the code
* @param message
* the message
*/
private UtilEnumCode(String code, String message) {
this.code = code;
this.message = message;
}
/**
* Gets the code.
*
* @return the code
*/
public String getCode() {
return code;
}
/**
* Gets the message.
*
* @return the message
*/
public String getMessage() {
return message;
}
}
策略模式-应用策略模式后的接口调用
@GetMapping(value = "/new")
public String test(String state) {
//state 传 add / update /delete
BaiduFaceService baiduFaceService = BaiduFaceFactory.getBaiduFace(state);
baiduFaceService.operation("153****7719", "123456", "98989897", "教师");
return "succ";
}
说明:没有if的判断,代码就两行。
总结
业务代码的行数减少,但是真正的业务代码放在实现类里面去了,真正的代码量其实是增加了,代码的逻辑和阅读难度增加了。有得就有失。