1. 程式人生 > 其它 >寫出可複用程式碼的基本思想與實踐

寫出可複用程式碼的基本思想與實踐

引言

“程式碼可複用性問題兼談團隊協作 ” 一文中,談到難以寫出可複用程式碼的一些不好的習慣和阻礙因素。本文講講寫出可複用程式碼的基本技巧和實踐。

程式碼可複用性,關鍵在於發現業務邏輯裡的通用性部分。同時,能夠發現業務邏輯裡的通用部分,並能提取出來,有助於做出更好的設計,提升研發效率。


基本思想

寫出可複用程式碼的基本思想,簡而言之,就是邏輯拆分。拆分粒度越細,可複用的可能性越高。通過拆分成一系列有層次的、細粒度的函式或方法,就能建立一個可複用的程式碼基礎。

拆分是戰術層面的事情。“戰略”層面,則需要對邏輯共性和差異的思考和提煉。通常包括兩層:


程式設計技巧

泛型和函數語言程式設計是一對強大的組合,有助於寫出精煉、可複用的程式碼。 可閱: “一次程式碼重構的思考及探索 ”


實踐

工具類

工具類是不依賴外部服務的“輸入-輸出”型函式。工具類最適合於做成可複用的,也容易寫單測。

比如:“構造與使用分離:命中內容高亮及合併的展示問題解決實現”

比如:“精練程式碼:一次Java函數語言程式設計的重構之旅 ” 重構得到的一系列 Util。


業務輔助類

業務輔助類是不依賴於外部服務的業務輔助工具類。這種類一般很小,能夠涵蓋很多業務點。而正是業務點的串聯,構成了主體業務邏輯。比如:


/**
 * 從 agentDetection 獲取可疑指令碼資訊
 */
public static ScriptDTO getScript(AgentDetection agentDetection) {
    if (AgentDetectionHelper.isInadequateAgentDetection(agentDetection)) {
        return null;
    }
    List<ScriptDTO> scripts = agentDetection.getAgentDetectionDetail().getDetail().getScripts();
    if (CollectionUtils.isNotEmpty(scripts)) {
        return scripts.get(0);
    }
    return null;
}


業務元件類

業務小元件類,依賴外部服務,提供單一的功能。 這種一般粒度比較小。封裝成小元件類很適合業務複用。這種業務小元件通常散落在各種 service 的 private 方法裡,而導致難以複用。


@Component
public class HostInfoHelper {
 
    private static final Logger LOG = LogUtils.getLogger(HostInfoHelper.class);
 
    private final HostProviderClient hostProviderClient;
 
    @Autowired
    public HostInfoHelper(HostProviderClient hostProviderClient) {
        this.hostProviderClient = hostProviderClient;
    }
 
    public HostDto getHost(String agentId) {
        if (agentId == null) {
            LOG.error("agentId is empty");
            return null;
        }
        HostDto host = hostProviderClient.getHost(agentId);
        if (null == host) {
            LOG.warn("No host found by agentId: {}", agentId);
            return null;
        }
        return host;
    }

}


統一機制的封裝

比如 ssdeep 檢測。 webshell 和 可疑指令碼的 ssdeep 檢測的邏輯基本相同。都是一段演算法 + 樣本檢測快取庫 + 樣本檢測記憶體快取 。 可以封裝成統一的。公司原始碼,就不便公開了。

統一機制需要指明呼叫來源,方便在必要的時候做差異處理。統一機制封裝有點類似微服務提供的外部介面。

有一定工作經驗的人是能夠理解我指的是什麼。

制訂標準資料格式

比如很多檢測能力都要用到檔案上傳。程序執行可疑指令碼檢測需要先上傳檔案,webshell 檢測也需要先上傳檔案。如果我要封裝一個業務功能,那麼首先要封裝出這個業務功能所需資訊的標準資料格式。然後根據這個資料格式來構建業務功能。


/**
 * 檔案上傳所需資訊
 * 目前檔案上傳下載主要依賴檔案的兩個資訊:
 * 1. md5
 * 2. fpath: 對於容器來說,fpath 是容器在宿主機裡的路徑
 *
 * Created by qinshu on 2022/1/11
 */
@Getter
@Setter
@Builder
public class IdsFileUploadInfo {
 
    /** 檔案MD5 */
    private String md5;
 
    /** 檔案 sha256 值,未來會用這個值 */
    private String sha256;
 
    /** 檔案路徑 */
    private String fpath;
 
    /** 業務來源,用於檔案上傳回調 */
    private String app;
 
    /** 作業系統平臺,不同平臺使用不同上傳指令碼 */
    private int osType;
 
    /** 上傳優先順序 */
    private int priority;
 
    /** 檔案儲存天數,可選 */
    private int keepDays;
 
    /** 主機ID, 可選 */
    private String agentId;
 
    /** 客戶ID,可選 */
    private String comId;
 
    /** 業務物件ID,用於查詢關聯業務表, 可選 */
    private String bizId;
 
    /** 檔案上傳後是否需要回調,一般是需要回調,更改任務表狀態 */
    private boolean callback = Boolean.TRUE;
}


共享庫封裝

更大層面複用的就是共享庫封裝。比如入侵檢測流程,基本可以看成是一系列元件的執行。每一個元件都可以是可複用的。

可閱: “事件處理業務的簡易元件編排框架”


小結

本文提煉了寫出可複用程式碼的一些基本技巧及實踐。 要寫出可複用的程式碼,基本思想是邏輯拆分。泛型和函數語言程式設計是一對強大的組合,有助於寫出精煉、可複用的程式碼。具體的工程技術手段有:

  • 工具類
  • 業務輔助類
  • 業務小元件
  • 統一機制封裝
  • 制訂標準資料格式
  • 共享庫。