我不認爲你應該考慮任何這些屬性作爲實際的成員變量。你應該有一個「屬性」對象,它包含一個屬性(這將類似於一個成員變量)和一個具有屬性集合的「集合」對象(它將像一個類)。
由於這些屬性和集合真的沒有與它們相關的代碼,這將毫無意義,以實現它們的對象(將在屁股真正的痛苦)
你的屬性和集合需要保存所有特定於他們的數據。例如,如果一個字段最終寫入數據庫,它需要將表名存儲在某個地方。如果需要寫入屏幕,那也需要存儲在某個地方。
範圍/值檢查可以「添加」到屬性,因此當您定義屬性的數據類型時,可能會有一些文本顯示「MaxLength(12)」,它將實例化一個名爲MaxLength的類值12,並將該類存儲到屬性中。只要屬性的值發生變化,新的值就會被傳遞給已經應用到這個類的每個範圍檢查器。可以有多種與該課程相關的動作。
這只是基礎。我已經設計出這樣的東西,這是一個很好的工作,但它比試圖用一種直白的語言簡單得多。
我知道這看起來像是太多的工作了(它應該如果你真的得到我建議的),但記住它,最終你可能會去「哼,也許這是值得的嘗試畢竟「。
編輯(迴應評論):
我想過嘗試與註冊表/關鍵的事情(我們還在討論屬性值對)工作,但它不太適合。
您試圖將DAO放入Java對象中。這真的很自然,但我認爲這只是解決DAO/DTO問題的一種不好的方法。 Java對象具有對這些屬性起作用的屬性和行爲。對於你正在做的事情,沒有任何行爲(例如,如果用戶創建一個「生日」字段,你將不會使用目標代碼來計算他的年齡,因爲你不知道生日是什麼)。
所以,如果你拋棄了對象和屬性,你將如何存儲這些數據?
讓我走一個非常簡單的第一步(非常接近您提到的註冊表/標記系統):在哪裏使用對象,使用散列表。對於屬性名稱,使用鍵,對於屬性值,使用散列表中的值。
現在,我將介紹我用來增強這個簡單模型的問題和解決方案。
問題: 你已經失去了強類型,你的數據是非常自由的格式(這可能是壞的)
解決方案: 作出「屬性」基類中的場所使用散列表中的值。擴展IntegerAttribute,StringAttribute,DateAttribute,...的基類不要允許不適合該類型的值。現在你已經擁有了強大的輸入,但它是運行時而不是編譯時 - 可能沒問題,因爲你的數據在運行時實際上是DEFINED的。
問題: 格式化程序和驗證程序
解決方案: 必須創建一個插件爲您的屬性基類的能力。您應該可以爲任何屬性設置「setValidator」或「setFormatter」。驗證器/格式化程序應該使用該屬性 - 因此,當您保存屬性時,您可能必須能夠將它們序列化到數據庫。
這裏很好的一點是,當你在屬性上執行「attribute.getFormattedValue()」時,它已經預先格式化顯示。如果任何驗證失敗,attribute.setValue()將自動調用驗證器並拋出異常或返回錯誤代碼。
問題: 如何在屏幕上顯示這些信息?我們已經有了getFormatted(),但它在屏幕上顯示的是什麼?我們用什麼標籤?什麼樣的控件應該編輯這個字段?
解決方案: 我會將所有這些東西存儲在每個屬性中。 (順序應該存儲在類中,但是因爲這是一個哈希表,所以它不會工作 - 那麼我們會在下一步)。如果您存儲顯示名稱,用於呈現此內容的控件類型(文本字段,表格,日期...)和數據庫字段名稱,則此屬性應具有它需要與顯示和數據庫I/O例程編寫來處理屬性。
問題: 該Hashtable是一個糟糕的DAO接口。
解決方案: 這是絕對正確的。你的散列表應該被包裝在一個知道它所擁有的屬性集合的類中。它應該能夠將自身(包括其所有屬性)存儲到數據庫 - 可能需要輔助類。它應該可以通過一個方法調用來驗證所有的屬性。
問題: 如何實際使用這些東西?
解決方案: 由於它們包含自己的數據,因此它們在系統中任何與它們交互的地方(比如屏幕或數據庫)都需要一個「適配器」。
假設您正在展示一個屏幕來編輯您的數據。您的適配器將傳遞一個框架和一個基於散列表的DTO。
首先它會按順序遍歷屬性列表。它會問第一個屬性(比如一個字符串)它想要用來進行編輯的控件類型(比如文本字段)。
它會創建一個文本字段,然後它會將一個偵聽器添加到將更新數據的文本字段,這會將您的數據綁定到屏幕上的控件。
現在只要用戶更新控件,更新就會發送到屬性。該屬性存儲新值,你就完成了。
(這將通過一個「OK」按鈕,所有的值在一次遷移的概念很複雜,但我仍然會設專人之前每個綁定,然後使用「OK」作爲觸發。)
這種綁定可能很困難。我用手工完成了這個工作,一旦我使用了一個名爲「JGoodies」的工具包,這個工具包內置了一些綁定功能,這樣我就不必親自編寫每個可能的綁定組合,但是我不確定從長遠來看它節省了很多時間。
這太長了。我將在某一天創建一個DAO/DTO工具包 - 我認爲Java對象完全不適合作爲DAO/DTO對象。
如果您仍然難住,請隨時Email/IM me - billmail在gmail ..
我不想與任何特定系統緊密聯繫,但我已經在考慮使用Apache Jackrabbit作爲後備存儲。我大多需要一個很好的DAO模型來表達一個好的通用接口。 – BobMcGee 2009-04-23 20:01:05
我對Jackrabbit並不熟悉,但看起來它實現了Java內容庫規範。該規範應該爲您提供通用節點,屬性等API。至於DAO,看起來Spring對JCR有很好的支持,並且使用它們的框架實現了DAO: https://springmodules.dev.java。 net/docs/reference/0.6/html/jcr.html – Andrew 2009-04-23 20:11:42