scala - Clojure GUI 编程很难

标签 scala clojure mocking mvp

我正在使用 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 世界中非常流行的选项:

  • CLJFX如果您同意从 Swing 迁移到 javafx。
  • Seesaw如果你宁愿继续摆动。

  • 编辑:最新信息:https://tonsky.me/blog/skija/

    关于scala - Clojure GUI 编程很难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5620897/

    相关文章:

    javascript - 如何在 componentDidMount 中模拟类函数

    unit-testing - 有哪些可用于 D 的模拟对象库?

    algorithm - Scala 流方法 takeWhile

    scala - SBT 解析器在 build.sbt 中工作,在 Build.scala 中不起作用

    emacs - 在 cider repl 中打印执行输出

    clojure 就像 F# 中的 cond

    laravel-5 - 如何模拟 PHPUnit 的 Guzzle 请求

    scala - ZIO Fiber orElse 生成异常消息

    scala - 显示目录名称和文件架构的 Json 架构

    clojure - 有关于 ClojureCLR 的任何像样的文档或教程吗?