2009-02-19 61 views
1

奇怪的問題,但我不知道它是否反模式。您的回調應用「深入」是不好的做法嗎?

說我有一個web應用程序將呈現1000個記錄到一個html表格。

我見過的典型方法是將查詢發送到數據庫,將記錄以某種方式轉換爲某種抽象狀態(例如數組或對象等),並將翻譯後的記錄放入然後在視圖中迭代該集合。

隨着記錄數量的增長,這種方法會佔用越來越多的內存。

爲什麼不隨查詢一起發送一個回調,該回調在從數據庫中讀取每個翻譯行時執行操作?這意味着您不需要爲視圖中的進一步迭代收集數據,因此內存佔用空間會縮小,而且您不會對數據進行兩次迭代。

這種方法肯定有一些隱含的錯誤,因爲我很少看到它在任何地方使用。這種方法有什麼問題?

謝謝。

回答

4

實際上,這正是一個完善的應用程序應該如何表現。

這種方法沒有什麼問題,只是不是所有的數據庫接口都允許您輕鬆地完成此操作。

如果我們討論爲另一個社交網絡製作10記錄,那麼如果您可以通過一個已經爲您實現的單個調用獲取一列哈希或任何其他內容,則不需要混淆回調。

0

這大致是迭代器模式允許您執行的操作。在很多情況下,這會在應用程序和數據庫之間的接口上發生故障。像LINQ這樣的技術甚至有可以將代碼發送回數據庫的解決方案。

1

這種方法肯定會有一些隱含的錯誤,因爲我很少在任何地方看到它。

我使用它。經常。即使我不會使用太多內存來重複複製數據,使用回調看起來更清晰。在使用閉包的語言中,它還可以讓您將相關的代碼保存在一起,同時將雜亂的數據庫內容分解出來。

1

這是一個「受工具限制」類的問題:大多數編程語言不允許說「圍繞此代碼做些事情」。近年來隨着關閉的出現,這個問題得到了解決。將閉包看作將代碼傳遞到另一個方法然後在上下文中執行的一種方式。例如,在GSQL,你可以寫:

def l = [] 
sql.execute ("select id from table where time > ?", time) { row -> 
    l << row[0] 
} 

這將打開一個到數據庫的連接,創建一個聲明和結果集,然後運行l << it[0]每行的DB回報。請注意,代碼在sql.execute()內部運行,但它可以訪問在sql.execute()row)中定義的變量的局部變量(l

使用這種代碼,您甚至可以隨時生成HTTP請求的結果,而無需隨時在RAM中保留大部分頁面。就我而言,我只用幾KB的內存就可以將一個2MB的文檔傳輸到瀏覽器,然後瀏覽器會咀嚼83s來解析它。

0

我發現使用接口解析器比深回調更容易,它通過幾個類連接起來。 MS的版本比我的Unity更有趣。這提供了一種更加清潔的訪問不應緊密耦合的類的方法

http://www.codeplex.com/unity

相關問題