我正在使用 Swing GUI 编写一个实用程序。我正在尝试使用 Martin Fowler 的 Presentation Model以方便测试。我的应用程序将使用 java.util.prefs.Preferences
自动存储多个用户首选项(即:主窗口位置和大小)。周末我花了几个小时试图创建 Preferences
的 Clojure 模拟。 API(使用 EasyMock )以便我可以测试演示者代码,但无法使其正常工作。对于长期的 OO 程序员来说,使用非 OO 风格的 Clojure GUI 编程很难。我觉得如果我能发现/开发这些东西的模式(模拟、视觉“类”的“接口(interface)”等),我可以在应用程序的其余部分继续使用相同的模式。
我也一直在 Scala 中开发相同的应用程序来比较编程模式,并发现它更直观,即使我试图以相当严格的函数风格使用 Scala(当然,不包括对 Java 类的调用,如Swing API——它在 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 的使用非常基本。
最佳答案
检查这两个在 clojure 世界中非常流行的选项:
编辑:最新信息:https://tonsky.me/blog/skija/
关于scala - Clojure GUI 编程很难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5620897/