2012-02-07 51 views
2

上下文:我有一個基於clojure的填字遊戲應用程序,其主UI是具有兩個選項卡,網格和線索表的JTabbedPane。線索表是一個包含線索向量的視圖,但向量本身不是數據的權威存儲區,而是通過一個(active-cluelist)函數從一些內部數據結構動態生成,由線索選項卡觸發。這個擺臺模型代碼設計不好嗎?

所以這就是線索表的實現:

(def cluelist []) 
(def update-cluelist) 
(def model) 

(defn make [] 
    (let [column-names ["Sq" "Word" "Clue"] 
     column-widths [48 200 600] 
     table-model (proxy [AbstractTableModel] [] 
         (getColumnCount [] (count column-names)) 
         (getRowCount [] (count cluelist)) 
         (isCellEditable [row col] (= col 2)) 
         (getColumnName [col] (nth column-names col)) 
         (getValueAt [row col] (get-in cluelist [row col])) 
         (setValueAt [s row col] 
            (let [word (get-in cluelist [row 1])] 
            (add-clue word s) ; editing a cell updates the main clue data 
            (def cluelist (assoc-in cluelist [row 2] s)) 
            (. this fireTableCellUpdated row col)))) 
     table (JTable. table-model) 
     ] 

; some pure display stuff elided 

(def model table-model) 
) 

(defn update-cluelist [] 
    (def cluelist (active-cluelist)) 
    (.fireTableDataChanged model)) 

有人在另一個討論中指出,它是(update-cluelist)手動調用fireTableDataChanged主代碼異味,因爲沒有爲TableModel類之外應該永遠是調用該方法。但是,我覺得這是表格從外部動態生成的不可避免的後果。該文檔是不是太有幫助 - 他們指出

您的自定義類只需要通過一個 外部源來調用一個下列 AbstractTableModel的方法每次表數據被改變。

它隱含地假定CustomTableModel類是數據的權威來源。

還出現了一個有點Clojure的/ java的阻抗不匹配的位置 - 在Java中我會用Clojure cluelist和臺式有cluelistupdate-cluelist是我的TableModel的私有成員和方法,而動態範圍的瓦爾那update-cluelist可以訪問。

我的主要問題是沒有太多的clojure/swing代碼,我可以尋找最佳實踐。有沒有人有任何建議,以最好的方式來做到這一點?

+1

_someone_ being me :-) – kleopatra 2012-02-07 12:32:20

+0

kleopatra:是的:)謝謝讓我重新審視設計! – 2012-02-07 23:28:56

回答

2

建議:使用原子作爲線索手。不斷重新定義cluelist並不是表示可變數據的正確方法。老實說,我希望它會在第二次定義線索時引發異常。

如果您使用原子作爲線索手,您可以從觀察者調用fireTableDataChanged方法,而不是手動調用它。這意味着您隨時(和在任何地方)更改原子,fireTableDataChanged將被自動調用,而無需顯式調用。

def的問題是多次調用def在多線程環境中不能很好地工作,並且Clojure試圖使一切都默認爲相當線程安全。據我瞭解,使用var的「正確」方式是單獨保留其根綁定(即,不要再次調用def),如果需要在本地更改它,則使用bindingdef可能會按照您使用它的方式工作,但是在這種情況下,語言設置爲支持原子,參考或代理,並且這些可能在大多數情況下都會更好(即您獲得觀察者)。另外,如果稍後添加它們,則無需擔心線程。

+0

原子絕對看起來像一個好主意,因爲當你注意到我可以添加一個觀察者,但爲什麼var是錯誤的?我見過clojure代碼中經常使用的變量來存儲不需要併發寫入的「可變」數據結構。 – 2012-02-07 22:51:26

+0

@MartinDeMello查看擴展答案 – Retief 2012-02-07 23:12:59

+0

謝謝,這確實有道理。 – 2012-02-07 23:28:18