一種DTO的規划方案


現在以網頁發布的軟件非常普遍,叫BS模式。前后端分離也是大趨勢,或者說逐漸普及開來,深受前后端程序員的喜愛,我還是習慣以程序員來泛稱所有軟件制作者。后端需要把數據傳送給前端,往往是通過DTO的序列化來實現的,而不是直接產生json或xml格式的數據。這里不說為什么要用DTO,只說探討一個問題,不同的api接口(方法)返回不同格式的數據,這些DTO要如何設計。

特別說明,以下說到的DTO,是指DTO類,而不是DTO實例。雖然O應該是指實例,但這里繼續用這個詞,不阻礙意思的表述。

方案一,需要什么造什么。

這個方案簡單,每個接口需要的數據結構不同就造不同的DTO,相同就復用。一般情況下能復用的不多,於是會出現大量的DTO,這些DTO的命名和管理成為難題。若規定一個接口獨立使用一個DTO,則寫這些DTO的工作量不小。還有一種粗糙的辦法,假設有100個DTO,把它們按相近程度划分為少數若干類DTO,假設10類吧,然后同一類的DTO屬性合並成一個DTO,這樣確實能有效減少DTO的數量,但在具體的應用時,會多出來許多很是奇怪的屬性。不可取。

方案二,照着對象造DTO

這里的對象可以簡單理解為數據表,一個數據表對應一個DTO,但是多對多的關系表不對應DTO。造出來的DTO基本上與數據表的數量一樣多(含統計功能的查詢除外),有效的控制了DTO的數量,命名也方便。一個缺點是每個表的全部字段不管是否用到都在DTO中,有些字段只在少數情況下使用的,也得到處出現。另一個缺點是在DTO之間的關系上幾乎總是造成循環引用。比如子對象往往要引用父對象,而父對象也有子對象的集合。不同接口往往只需要表現其中一個方向,但做出來的兩個DTO類之間就必然有這種相互引用的關系,在自動生成api文檔的時候,這種循環引用會是個問題,至今沒有找到好的解決辦法。

方案三,一個對象對應N個DTO

這N個DTO我作了規划:

類型 基類 范圍
DTO1 只有ID和Name
DTO2 DTO1 只有常用的屬性
DTO3 DTO2 有全部的屬性,但不包含IsDeleted這類特殊的附加屬性
DTO4 DTO3 包含了父對象
DTO5 DTO3 包含了子對象
DTO6 DTO4 包含了父對象和子對象

DTO4,DTO5,DTO6引用其它的DTO,作為泛型在具體使用的時候傳入,並約束為對應的DTO1本身或子類。
這樣,就可以以有限的數量的DTO,來組合表達足夠靈活的結構,同時不會有輸出太多多余的屬性的情況。
也能解決DTO之間的循環引用問題,從而能使用swagger等生成api文檔。

以學生和班級為例:

  1. 需要按條件查到若干個學生和每個學生對應的班級名稱,則是結構是:
List<學生3<班級1>> 學生列表;
  1. 需要得到若干個班級,以及每個班級的部分符合指定條件的學生
List<班級5<學生2>>
  1. 需要得到指定老師所教的全部班級的學生,則是
老師5<班級5<學生2>>

缺點也是有的,DTO有6個,雖然有繼承,不用重復寫,但總比只有1個DTO要多寫點代碼。另外,這些DTO如何區分命名比較好,也是一個有待進一步完善的問題。如上表,是以數字123456區分的,應該有更好的命名方案。

  • 2019-03 經過項目的實際使用, 調整為以下方案, 更適應實際的應用的需要。
類型 基類 范圍
DTO1 ID和Name(Code)
DTO2 DTO1 只有常用的屬性
DTO3 DTO2 全部屬性(不包含IsDeleted這類特殊的附加屬性,下同)
DTO4 DTO2 常用屬性+父對象
DTO5 DTO2 常用屬性+子對象
DTO6 DTO4 常用屬性+父對象+子對象
DTO7 DTO3 全部屬性+父對象
DTO8 DTO3 全部屬性+子對象
DTO9 DTO7 全部屬性+父對象+子對象


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM