一種DTO的規劃方案

2022-03-05 16:35:38 字數 1965 閱讀 5526

現在以網頁發布的軟體非常普遍,叫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類之間就必然有這種相互引用的關係,在自動生成api文件的時候,這種迴圈引用會是個問題,至今沒有找到好的解決辦法。

這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文件。

以學生和班級為例:

需要按條件查到若干個學生和每個學生對應的班級名稱,則是結構是:

list《學生3《班級1>> 學生列表;
需要得到若干個班級,以及每個班級的部分符合指定條件的學生

list《班級5《學生2>>
需要得到指定老師所教的全部班級的學生,則是

老師5《班級5《學生2>>
缺點也是有的,dto有6個,雖然有繼承,不用重複寫,但總比只有1個dto要多寫點**。另外,這些dto如何區分命名比較好,也是乙個有待進一步完善的問題。如上表,是以數字123456區分的,應該有更好的命名方案。

型別基類

範圍dto1

id和name(code)

dto2

dto1

只有常用的屬性

dto3

dto2

全部屬性(不包含isdeleted這類特殊的附加屬性,下同)

dto4

dto2

常用屬性+父物件

dto5

dto2

常用屬性+子物件

dto6

dto4

常用屬性+父物件+子物件

dto7

dto3

全部屬性+父物件

dto8

dto3

全部屬性+子物件

dto9

dto7

全部屬性+父物件+子物件

URL重寫的一種方案

url重寫可以讓 看上去更有條理 還可以讓 改版後的舊連線能夠繼續使用。可以參考可用性專家jakob neilsen對url的建議 msdn相關參考 中文 英文 考慮到簡潔,為什麼每個url最後都要是aspx呢?因為如果不是aspx,就無法對映到aspnet中進行處理。想要實現將 2004 這樣的目...

Nginx一種限流方案

介面為了防止高併發拖累系統 通過nginx來限流 如最多同時允許100個使用者進來 超過100個則預設返回未中獎 lua init r.lua local shared data ngx.shared.dict shared data set draw 0 draw r.lua local requ...

Lua 實現switch的一種方案

local et case one 1 local et case two 2 local function do case one print do case one endlocal function do case two print do case two endlocal function...