大家好,我是小寧
這半個月鼓搗了不少工具類,搞著搞著發(fā)現(xiàn),這些工具類雖然功能不一樣,但是封裝的思路和組織的方式很像,可以提煉出一些共同點出來, 這是很值得分享的事.
所謂授人以魚,不如授人以漁,可能看我的文章,代碼沒學會幾行,但相信我,收獲的絕不止是代碼
工具類案例
先看下我這段時間的成果(安裝包還沒在網上發(fā)布,可以找我拿安裝包)
工具類源碼示例
我選取了幾個工具包展示出來,可以看到,一個工具的組成,大致由三種類組成: 1. xxxConfig. 2. xxxTools. 3.model包,存放工具的請求/返回實體
我們以釘釘?shù)墓ぞ甙鼮槔M行剖析:
DingConfig.java
public class DingConfig {
// 釘釘添加機器人時獲得的url
private String url;
// 釘釘添加機器人時獲取的secret
private String secret;
// 在原有的URL之上添加一些參數(shù)
public String getUrl() {
Long timestamp = System.currentTimeMillis();
String sign = getSign(timestamp);
returnurl+"×tamp="+timestamp+"&sign="+sign;
}
/**
* 通過時間戳和sercet進行加密.
*/
public String getSign(Long timestamp) {
try {
String stringToSign = timestamp +"\n"+ secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"),"HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
returnURLEncoder.encode(Base64.getEncoder().encodeToString(signData),"UTF-8");
}catch (Exception e){
returnnull;
}
}
}
如上所示,我們可以看到,這個配置類不僅僅是存一些值, 一些常用的和配置相關的功能也都在這里,這里有點像領域驅動的充血實體類的感覺了.
DingMessage.java 已精簡掉相關的get/set方法
public class DingMessage {
// 定義釘釘消息的類型,純文字類型
public static final String TYPE_TEXT="text";
// 定義釘釘消息的類型,帶按鈕可跳轉的類型
public static final String TYPE_ACTION_CARD ="actionCard";
privateString? msgtype;
privateTextMessage text;
privateActionCardMessage actionCard;
// 采用靜態(tài)內部類的形式來組織嵌套的實體類
static class TextMessage{
privateString content;
public String getContent() {
return content;
}
}
// 采用靜態(tài)內部類的形式來組織嵌套的實體類
static class ActionCardMessage{
privateString title;
privateString text;
privateString hideAvatar;
privateString btnOrientation;
privateList btns;
}
// 采用靜態(tài)內部類的形式來組織嵌套的實體類
static class DButton{
privateString title;
privateString actionURL;
}
// 對外提供的初始化函數(shù),對外部看來,只需要傳一個content就可以了
// 拼實體類的操作,放到了實體類里面
public static DingMessage initTextMessage(String content){
TextMessage textMessage = new TextMessage();
textMessage.content = content;
DingMessage dingMessage = new DingMessage();
dingMessage.text = textMessage;
dingMessage.msgtype = TYPE_TEXT;
return dingMessage;
}
}
通過我們和第三方都是通過json的方式進行交互. 要么就是map轉json,要么就是實體類轉json, 這里我都是使用的實體類轉json, 也沒有拆分很多的實體類,直接通過靜態(tài)內部類就可以完成實體的組織
DingTools.java
// 提供給外部使用的工具類
public static void sendText(String content,DingConfig config){
? ? ? ? // 構造請求實體類
? ? ? ? DingMessage message = DingMessage.initTextMessage(content);
? ? ? ? // 轉成json
? ? ? ? String s = JSON.toJSONString(message);
? ? ? ? // 請求第三方
? ? ? ? HttpResponse<String> response = HttpTools.doPost(config.getUrl(),s , HttpRequest.JSON_HEADER, String.class);
? ? ? ? // 處理返回值
? ? ? ? System.out.println(response.getBody());
? ? }
如上源碼所示,真得到工具類里面大致分為四步, 構造請求實體類,轉成json,請求, 然后處理返回值,同樣的去請求微信/redis,也大致都是這個結構
調用方
public static void main(String[] args) {
// 配置config
DingConfigconfig= new DingConfig();
config.setUrl("https://oapi.dingtalk.com/robot/send?access_token=xx");
config.setSecret("xxxx");
// 調工具類
DingTools.sendActionCard("測試審核","這是一條測試審核的信息",config);
}
對調用方來說, 就兩個事, 拼Config , 然后調用工具類. 通過傳入的Config不一樣, 工具類可以操作不同主體的第三方, 這個跟所謂的無狀態(tài)就很像了
總結
思路思路, 本篇文章只要強調的是思路, 大家以后在封裝自己的工具類時,也可以考慮使用這樣的結構, 一個Config , 一個實體包, 一個Tools. 這樣對調用方和對自己來說,都很簡單.