一倘零、簡介
json-diff是一款強大的,由java編寫的json差異發(fā)現(xiàn)工具。他可以發(fā)現(xiàn)任何結(jié)構(gòu)的json差異绰上,并且將差異信息反饋給用戶。
gitee: https://gitee.com/codeleep/json-diff
教程:https://juejin.cn/post/7210003299109109818
給大家提供一個設(shè)計json-diff的實現(xiàn)思路渠驼,用于發(fā)現(xiàn)json的差異蜈块,對比json。
二迷扇、需求
精準定位差異所在
詳細的差異位置
能支持豐富的差異過程控制
1. 基礎(chǔ)設(shè)計
1.1 json 結(jié)構(gòu)抽象
我們知道百揭,在 json
中,只存在三種結(jié)構(gòu)蜓席。
數(shù)組[]
:數(shù)組元素可以由任意json
結(jié)構(gòu)組成器一。對象{}
:對象是一個key-value
的列表。key
只由字符串組成,value
可由任意json
結(jié)構(gòu)組成數(shù)據(jù)單元
: 一個最小數(shù)據(jù)單元厨内∑盹酰可以是String
,Number
等基礎(chǔ)結(jié)構(gòu)
為了簡化,我們簡單的認為 對象的
key
只由字符串組成雏胃,value
可由任意json
結(jié)構(gòu)組成
這樣我們就得到了一個基礎(chǔ)的概念请毛。json 結(jié)構(gòu)中,只有 數(shù)組的 item
和 對象的 value
存在變化丑掺。且變化范圍是 json 結(jié)構(gòu)获印,也就是上述三種結(jié)構(gòu)。
1.2 遍歷模型抽象
為了將復雜的問題拆解成若干個小問題街州,我們就需要高度抽象整個過程重復過程兼丰。
既然上述將數(shù)據(jù)抽象成一個規(guī)范的結(jié)果,也明確知道只有 數(shù)組的 item
和 對象的 value
存在變化唆缴。那我們對不變化的部分做硬編碼鳍征,對變化的部分做適配即可。
也就是面徽,我們需要抽象出三種數(shù)據(jù)結(jié)構(gòu)的處理器:
- 數(shù)組處理器 (ComplexArrayJsonNeat):處理json數(shù)組結(jié)構(gòu)艳丛。遍歷數(shù)組匣掸,比較元素
- 對象處理器 (ComplexObjectJsonNeat):處理json對象結(jié)構(gòu)。遍歷所有key氮双,比較value
- 數(shù)據(jù)單元處理器 (PrimitiveTypeJsonNeat):直接對比兩個數(shù)據(jù)單元是否一致碰酝。不可向下拆分
有了三種處理器之后,我們就可以設(shè)計出以下這種遍歷結(jié)構(gòu)戴差。
上圖中的遍歷結(jié)構(gòu)結(jié)束的條件只有遍歷出所有的基礎(chǔ)單元送爸,這就是工具最核心的設(shè)計。其實看起來就很簡單暖释。
圖中有一個 Json結(jié)構(gòu)處理器
其實內(nèi)部很簡單袭厂,根據(jù)傳入的 expect節(jié)點
和 actual節(jié)點
判斷需要以什么類型處理器進行處理。當然避免不了多個 if 球匕。
這樣設(shè)計的好處是我們可以將所有的節(jié)點在方法棧中獨立纹磺,就不會存在數(shù)據(jù)污染問題,也會將問題簡化亮曹。但所帶來的開銷即是需要創(chuàng)建較多的相同對象橄杨。
2. 功能豐富
基于上述的遍歷模型,可以在其過程中進行很多外在干預照卦。
2.1 數(shù)組
- 忽略數(shù)組順序:對于數(shù)組遍歷
item
過程可以將數(shù)組順序忽略讥珍。
2.2 對象
-
key
映射:可以支持expect節(jié)點
和actual節(jié)點
中使用不同的key
的value
進行對比。比如將expect
對象中的a
字段與actual
對象的b
字段進行對比 -
key
忽略:如果不想關(guān)注某個key
窄瘟,可以支持該需求
2.3 基礎(chǔ)單元
- 支持所有java中的基礎(chǔ)類型,即jdk中重寫了eques的類
2.4 處理器前置檢測
- 忽略路徑:指定的路徑不比較
2.5 其他
- 支持自定義處理器
- 支持只關(guān)心結(jié)構(gòu)變化
本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布趟卸!