我正在使用Swing GUI編寫一個實用程序。我正在嘗試使用Martin Fowler的Presentation Model來促進測試。我的應用程序將使用java.util.prefs.Preferences
(即:主窗口位置和大小)自動存儲多個用戶首選項。我在週末花了幾個小時嘗試創建Preferences
API的Clojure模擬(使用EasyMock),以便測試演示者代碼,但無法使其工作。使用非OO風格的Clojure GUI編程對於長時間的OO程序員來說很難。我覺得如果我能夠發現/開發這些東西的模式(嘲笑,視覺「類」的接口等),我可以繼續在應用程序的其餘部分使用相同的模式。Clojure GUI編程很難
我也一直在開發Scala中的相同應用程序來比較編程模式,並發現它更直觀,即使我試圖在相當嚴格的功能樣式中使用Scala(當然不包括調用到像Swing API這樣的Java類 - 在Clojure版本中會有相同的可變性問題,但當然也會是單線程的)。
在我的Scala代碼中,我創建了一個名爲MainFrame
的類,該類擴展了JFrame
並實現了特徵MainView
。 MainView
公開所有的JFrame
電話爲抽象方法,我可以在模擬對象的實施:對於
trait LabelMethods {
def setText(text: String)
//...
}
trait PreferencesMethods {
def getInt(key: String, default: Int): Int
def putInt(key: String, value: Int)
//...
}
trait MainView {
val someLabel: LabelMethods
def addComponentListener(listener: ComponentListener)
def getLocation: Point
def setVisible(visible: Boolean)
// ...
}
class MainFrame extends JFrame with MainView {
val someLabel = new JLabel with LabelMethods
// ...
}
class MainPresenter(mainView: MainView) {
//...
mainView.addComponentListener(new ComponentAdaptor {
def componentMoved(ev: ComponentEvent) {
val location = mainView.getLocation
PreferencesRepository.putInt("MainWindowPositionX", location.x)
PreferencesRepository.putInt("MainWindowPositionY", location.y)
}
mainView.someLabel.setText("Hello")
mainView.setVisible(true)
}
class Main {
def main(args: Array[String]) {
val mainView = new MainFrame
new MainPresenter(mainView)
}
}
class TestMainPresenter {
@Test def testWindowPosition {
val mockPreferences = EasyMock.mock(classOf[PreferencesMethods])
//... setup preferences expectation, etc.
PreferencesRepository.setInstance(mockPreferences)
val mockView = EasyMock.createMock(classOf[MainView])
//... setup view expectations, etc.
val presenter = new MainPresenter(mockView)
//...
}
}
我使用的是僞單身(setInstance
包括在內,以便進行模擬可以代替「真實」的版本)首選項,所以細節不顯示。我知道蛋糕模式,但發現在這種情況下我的使用更容易一些。
我一直在努力做類似的代碼在Clojure。有什麼好的開源項目的例子可以做這種事情嗎?我已經閱讀了幾本有關Clojure的書(Clojure編程,Clojure的喜悅,實用Clojure),但是沒有看到這些問題處理過。我也研究過Rich Hickey的ants.clj
,但他在這個例子中使用Swing是非常基本的。
@dnolen:是的。我會重新閱讀它。謝謝。我認爲我發現最困難的是「重構」我的代碼而不是類的功能。有趣的是,自從我在上個世紀八十年代做了一大堆C編程。 – Ralph 2011-04-11 14:38:25
@Ralph:在大多數情況下,c中的「功能」是指「程序」。因此程序性而非功能性編程:) – 2011-04-11 17:42:36
@Vagif Verdi:是的。當我開始學習Clojure時,我意識到了這種差異,但在某種程度上,「動詞」而不是「名詞」的想法也適用於C程序編程。畢竟,「過程」是一系列影響對象的操作,即使這些對象確實是命令式的狀態。 – Ralph 2011-04-11 17:48:33