主頁 >  其他 > 關于介面可維護性的一些建議

關于介面可維護性的一些建議

2023-05-18 07:46:31 其他

作者:京東科技 D瓜哥

在做新需求開發或者相關系統的維護更新時,尤其是涉及到不同系統的介面呼叫時,在可維護性方面,總感覺有很多地方差強人意,一些零星思考,拋磚引玉,希望引發更多的思考和討論,總結了大概有如下幾條建議:

  1. 在介面注釋中加入介面檔案鏈接

  2. 將呼叫介面處寫上被呼叫介面檔案鏈接

  3. 將介面源代碼發布到私服倉庫

  4. 對于狀態值常量,優先在介面引數類或者回傳值類中定義

  5. 如果使用 Map 物件作為傳輸載體,要提供 Key 值定義常量

  6. 針對 Map 回傳值,可以考慮使用將 Map 轉化成物件

  7. 盡可能簡化介面依賴

  8. 只傳遞必要欄位,盡量避免大而全的介面

  9. 將介面的引數和回傳值原始資料列印到日志中

  10. 將 RPC 介面的類名及方法列印到日志中

  11. 核心思想:以人為本,就近原則,觸手可及

下面,D瓜哥對每一條建議做一個詳細說明,

1. 在介面注釋中加入介面檔案鏈接

在做介面開發時,無論是對自有介面的升級改造,還是針對外部介面的從頭接入,都涉及到介面檔案,不同之處是,前者的作業重點是書寫或者更新介面檔案;而后者是根據介面檔案開發合適的接入代碼,但是,經常遇到的一個麻煩是,找不到介面檔案,在組內需要找老同事詢問;如果是跨部門,還需要兩層甚至三層的進行轉接,非常麻煩,

D瓜哥認為,在這種情況下,為了方便大家維護,最好的辦法就是將介面檔案鏈接直接放在代碼注釋中,這樣后續維護的人員,直接就可以點擊鏈接直達介面檔案,簡單方便高效,如果是新建的介面,就可以先創建一個空檔案,把鏈接放在注釋中,后續再書寫檔案內容,如果是維護已有介面,可以在維護時,將缺失的鏈接加入到注釋中,自己方便,也方便其他人進行后續的維護更新,這樣,在循序漸進的程序中,逐步就可以把檔案鏈接補充到代碼中,方便維護代碼,也同步更新檔案,

2. 將呼叫介面處寫上被呼叫介面檔案鏈接

在呼叫其他系統的介面時,沒有介面檔案,幾乎寸步難行,在第一次接入介面時,絕大多數情況下,都是參考著介面檔案做接入作業,但是,目前的情況時,接入時參考檔案,參考完就隨手把檔案給“扔了”,后續如果還需要做進一步升級維護,還需要到處找介面檔案;另外,互動的系統難免有一些 Bug,在和其他系統維護人員對接處理 Bug 時,只有介面沒有檔案,對方可能也需要去找檔案鏈接,無形中,很多時間都浪費在了找檔案的程序中,

D瓜哥最近嘗試了一個實踐,就是在介面呼叫的地方,把介面檔案鏈接當做注釋加入到代碼中,這樣,無論是后續維護升級,還是溝通協調處理問題,都非常方便,別人問介面是什么,連介面+檔案都可以一把復制就搞定,

經過最近一段時間的實踐情況來看,這個處理非常方便,是一個非常值得推廣的實踐,再插一句,也可以像一條建議一樣,可以在維護代碼時,不斷把已接入的介面檔案加入到呼叫介面的地方,循序漸進,方便后續人維護升級,

3. 將介面源代碼發布到私服倉庫

介面檔案鏈接在注釋中,在構建結果中就不復存在了,所以,為了方便介面使用方可以在介面中查詢到對應的介面檔案,就需要把原始碼也發布到私服倉庫中,

這里只說明一下 Java 的相關處理辦法,如果使用 Maven 作為構建工具的話,默認是不會將源代碼發布到私服倉庫中的,關于如何將源代碼發布到,在 升級 Maven 插件:將原始碼發布到私服倉庫 中已經做過相關介紹,這里就不再贅述,

除了將原始碼發布到私服倉庫,另外,還建議編譯構建時,保持方法的原始引數命名,這個也可以通過配置 Maven 插件來完成,具體配置見: 升級 Maven 插件:位元組碼檔案包含原始引數名稱,

4. 對于狀態值常量,優先在介面引數類或者回傳值類中定義

在做介面開發時,很多資料都有一個狀態值,比如訂單狀態,再比如介面狀態等等,目前的一個情況時,這些狀態值大部分書寫在檔案中,在接入介面時,需要接入方自定義這些狀態值,這就有些繁瑣了,而且狀態定義也不明確,甚至有可能遺漏一些重要的狀態值,有些懶省事,直接在代碼中硬編碼一個魔法值,后續維護的跟還需要根據背景關系反推這個值的含義,非常不利于維護,

D瓜哥個人覺得,有兩個處理辦法:

  1. 如果狀態值不是很多,優先在介面引數類或者回傳值類中定義,

  2. 如果狀態值很多,可以考慮單獨抽取成一個常量類或者列舉類,

這樣使用的時候,觸手可及,不需要到處去找,

5. 如果使用 Map 物件作為傳輸載體,要提供 Key 值定義常量

有些系統可能考慮方便增加欄位,選擇使用 Map 作為資料載體,自己開發的時候很爽,但是給介面接入卻非常不友好,接入方從 Map 中獲取資料時,要么自己定義 Key 值;要么直接使用魔法值硬編碼在代碼中,使用前者方案,就需要在各個接入方都需要自定義一套;使用后者,初期是省事了,后來維護的人員就懵逼了,這都無形中增加了很多維護成本,

D瓜哥覺得一個方案更優,那就是直接由介面提供方來定義這些可以取值的 Key 值常量,這樣,任何接入方都可以直接使用這些常量,

6. 針對 Map 回傳值,可以考慮使用將 Map 轉化成物件

針對 Map 的處理,即使按照 如果使用 Map 物件作為傳輸載體,要提供 Key 值定義常量 推薦的做法,定義了相關的 Key,在取值時,也略有麻煩,需要不斷的 map.get(KEY),一個更簡單的方法是自定義一個型別,使用工具將 Map 物件轉化成自定義型別的物件,這樣就可以直接使用方法呼叫來取值,

在 Java 中,可以直接使用 Jackson 來完成這個轉換作業,工具類代碼如下:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;java

/**
 * Map 工具類
 *
 * @author D瓜哥 · https://www.diguage.com
 */
@Slf4j
public class MapUtils {
    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 將 Map 轉換成指定型別的物件
     *
     * @author D瓜哥 · https://www.diguage.com
     */
    public static <T> T convertToObject(Map<String, Object> data, Class<T> clazz) {
        try {
            T result = MAPPER.convertValue(data, MAPPER.getTypeFactory().constructType(clazz));
            if (log.isInfoEnabled()) {
                log.info("converted {} to a {} object: {}",
                        JsonUtils.toJson(data), clazz.getSimpleName(), JsonUtils.toJson(result));
            }
            return result;
        } catch (Exception e) {
            log.error("converting failed! data: {}, class: {}",
                    JsonUtils.toJson(data), clazz.getSimpleName(), e);
        }
        return null;
    }

    /**
     * 將 Map 轉換成指定型別的物件
     *
     * @author D瓜哥 · https://www.diguage.com
     */
    public static <T> List<T> convertToObjects(List<Map<String, Object>> datas, Class<T> clazz) {
        if (CollectionUtils.isEmpty(datas) || Objects.isNull(clazz)) {
            return Collections.emptyList();
        }
        List<T> result = new ArrayList<>(datas.size());
        if (CollectionUtils.isNotEmpty(datas)) {
            for (Map<String, Object> data : datas) {
                T t = convertToObject(data, clazz);
                result.add(t);
            }
        }
        return result;
    }
}


7. 盡可能簡化介面依賴

現在,很多對外暴露介面的定義是,介面定義放在一個模塊中;模型定義在一個模塊中;有些工具類又定義在一個模塊中,介面依賴模型模塊;模型模塊又依賴工具類模塊;而工具類依賴了一大堆外部依賴,個人覺得這是一個非常不好的實踐,會導致很多不必要的依賴被間接引入到了介面使用方的系統中,無形中增加很多維護成本,

D瓜哥推薦的一個實踐是:將介面和模型定義放在一個模塊中,對外暴露也只需要這一個模塊即可,介面使用方只需要引入這一個依賴,避免引入很多無用的其他外部依賴,如果模型需要依賴一些公共的父類,可以考慮將這些單獨定義在一個模塊中,這個模塊只保存多個系統依賴的公共類,并且剔除掉一些工具類的定義,這樣就可以保證介面依賴的純凈性,如果其他系統需要工具類,讓其明確去引入,而不是被動依賴,

對于前面 對于狀態值常量,優先在介面引數類或者回傳值類中定義 中提到了“如果狀態值很多,可以考慮單獨抽取成一個常量類或者列舉類,” 這里存在一種情況需要特別說明,狀態值的定義需要在本系統的業務模塊的代碼中使用,可以將介面的依賴加入到改業務模塊的依賴中,而不是反過來,為什么會這樣的操作?一個核心思想是保持對外暴露介面的純凈性,這樣既可以減少狀態定義的重復性,又可以減少介面的外部依賴,

8. 只傳遞必要欄位,盡量避免大而全的介面

觀察很多系統,尤其是一些以業務為核心的系統的對外暴露介面,很多介面是大而全的介面,一個介面就可以把指定資料的所有資訊全部回傳出去,這樣,很多欄位需要去識別,也要在眾多欄位中區篩選出來符合自己要求的資料,無形中浪費了很多心智,不利于維護,

D瓜哥認為,在做介面開發時,一定要做一個“吝嗇的守財奴”,把資料當做財富一樣守護,對外只提供必要的資料,做到“夠用就行”,

這一點不僅僅是維護上的考慮,還有資料傳輸效率的點,在其他條件相同的情況下,更小的資料,無論是機器處理效率,還是傳輸效率,都會更快更高,

關于傳輸效率上的一些思考,結合 Hessian、Msgpack 和 JSON 實體對比 以及 “Hessian 協議解釋與實戰” 等文章來看,有幾個原則值得重視的:

  1. 優先使用 boolean 型;

  2. boolean 型滿足不了,次優選擇 int 整型資料;再次可以考慮 long 型;

  3. 日期優先使用內置的日期型別(含 Java Time API 型別),而不是格式化成字串,

  4. 對于以上型別不滿足,則選擇使用字串,

  5. 集合型別,鏈表優先使用 ArrayList,也可以考慮使用 Iterator;哈希優先使用 HashMap;

  6. 以上情況都不符合要求才選擇自定義物件,

9. 將介面的引數和回傳值原始資料列印到日志中

據觀察,一些開發人員沒有將介面,尤其是 RPC 介面的引數及回傳值列印到日志中,這對定位問題非常不利,說的更直白一點,非常不利于甩鍋,當出了問題,不能第一時間就憑借引數及回傳值順利甩鍋,可能導致自己花很多時間去排查問題,最后發現是自己依賴的其他系統的問題,

所以,一定要謹記,將介面的引數和回傳值原始資料列印到日志中,D瓜哥憑借這個實踐,在一些客訴及反饋中,順利脫身,實作完美甩鍋,

10. 將 RPC 介面的類名及方法列印到日志中

D瓜哥也在嘗試一個實踐:將 RPC 介面的類名和方法,再加上引數或者回傳結果,同時列印到日志中,

這里為什么和上面的 將介面的引數和回傳值原始資料列印到日志中 單獨列出來?因為,在這個實踐中,強調的是 “RPC 介面”,相對來說, RPC 介面存在更多容易出錯的問題,經常需要脫離系統去單獨測驗 RPC 介面的可用性,把類名就方法名可以更方便在出現問題時,就可以及時根據日志中的資訊,去單獨測驗 RPC 的可用性,

11. 核心思想:以人為本,就近原則,觸手可及

洋洋灑灑總結了這么幾條建議,這里做一個總結,

對于可維護性建議的一個核心思想就是:以人為本,就近原則,觸手可及,通常來說,人都是有一定的惰性的,如果把飯端到眼前,相信任何正常人無法抗拒美食的傭訓,而這里提到的一些可維護性的點,就是盡可能照顧人“懶”的特性,在第一次時,就把該做的作業做到位,減少后續人員不必要的麻煩,讓人可以“合法偷懶”,

加油!爭取讓更多人可以更好地偷懶,????????????

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/552687.html

標籤:其他

上一篇:自動化測驗基礎知識,你知道的不知道的都在這里

下一篇:返回列表

標籤雲
其他(159191) Python(38148) JavaScript(25431) Java(18055) C(15228) 區塊鏈(8267) C#(7972) AI(7469) 爪哇(7425) MySQL(7191) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5340) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4572) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2433) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1975) 功能(1967) Web開發(1951) HtmlCss(1938) python-3.x(1918) C++(1917) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1861) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 關于介面可維護性的一些建議

    在做新需求開發或者相關系統的維護更新時,尤其是涉及到不同系統的介面呼叫時,在可維護性方面,總感覺有很多地方差強人意。一些零星思考,拋磚引玉,希望引發更多的思考和討論。總結了大概有如下幾條建議: ......

    uj5u.com 2023-05-18 07:46:31 more
  • 自動化測驗基礎知識,你知道的不知道的都在這里

    借助測驗工具,依照測驗規范,區域或全部代替人工測驗,提高測驗有效性。
    備注:測驗不需要對軟體所有功能進行測驗,比如很多軟體的幫助。 ......

    uj5u.com 2023-05-18 07:46:15 more
  • 最佳軟體測驗基礎入門教程3軟體開發生命周期的測驗

    軟體開發生命周期的測驗 本章簡要介紹了軟體開發專案中常用的生命周期模型,并解釋了測驗在每個模型中扮演的角色。它討論了各種測驗級別和測驗型別之間的區別,并解釋了這些在開發程序中的應用位置和方式。 大多數軟體開發專案是按照事先選擇的軟體開發生命周期模型來計劃和執行的。這種模型也被稱為軟體開發程序模型,或 ......

    uj5u.com 2023-05-18 07:46:01 more
  • 軟體測驗精品書籍檔案下載

    測驗基礎 Google軟體測驗之道 強烈推薦 下載 Google軟體測驗之道-2016 How Google Tests Software-2012_.pdf: https://url97.ctfile.com/f/18113597-857996829-9531f6? 獲取訪問密碼 公眾號:pyth ......

    uj5u.com 2023-05-18 07:45:36 more
  • 最佳軟體測驗基礎入門教程4靜態測驗

    靜態測驗 對作業產品(檔案和代碼)進行靜態測驗和分析,對提高產品質量有很大的幫助。本章介紹了靜態測驗的一般情況,以及所涉及的具體程序,包括其活動和必須填補的角色。我們描述了四種經過驗證的技術和它們的具體優勢,以及在應用它們時確保成功的因素。最后,我們比較了靜態和動態測驗技術。 被低估的技術 靜態測驗 ......

    uj5u.com 2023-05-18 07:45:21 more
  • [SWPUCTF 2021 新生賽]PseudoProtocols

    ##看到提示和地址欄 很明顯了吧 偽協議 base64解碼可得 <?php //go to /test2222222222222.php ?> <?php ini_set("max_execution_time", "180"); show_source(__FILE__); include('fl ......

    uj5u.com 2023-05-18 07:45:00 more
  • Http協議和決議實戰

    一、瀏覽器的B-S架構和C-S架構 1、C-S架構:客戶機-服務器,簡單點就是需要下載的軟體,相關資源(圖片、視頻等會比較流暢),但是也缺少通用性(各種手機兼容),系統維護性,升級需要重新設計和開發,增加了維護和管理的難度。 2、B-S架構:瀏覽器和服務器架構模式,WEB瀏覽器是客戶端最主要的應用軟 ......

    uj5u.com 2023-05-17 07:55:42 more
  • 如何用技術改變生活

    搞了那么多年的開發,最后發現關注程式員群體的人還挺少的,我這里把遇到的問題和解決方案分享一下,希望能碰撞出不同的火花。
    誰都希望生活更好一點,我也希望,同時,我也在做這樣的事情,希望有更多的人會更好,也讓我學習和借鑒一下。 ......

    uj5u.com 2023-05-17 07:55:01 more
  • [SWPUCTF 2021 新生賽]ez_unserialize

    題目在哪呢?查看源代碼試試 User-agent: * Disallow: 什么東西呢 發現disallow Robots 協議(也稱為爬蟲協議、機器人協議等)的全稱是 “網路爬蟲排除標準”(Robots Exclusion Protocol),網站通過 Robots 協議告訴搜索引擎哪些頁面可抓, ......

    uj5u.com 2023-05-17 07:54:32 more
  • UE5 材質 雨滴shader

    潮濕效果 物體表面是如何變濕的? 物體表面吸水使顏色變深 潮濕的顏色會變得暗淡且飽和 實作 增加飽和度且變暗 潮濕的物體表面的特點 當水作用在材質表面,材質表面的==specualr==會略微變弱且==粗糙度==會大幅降低 對于積水的表面,我們設定它的roughness = 0.07, specua ......

    uj5u.com 2023-05-17 07:49:09 more