在Clojure中使用前提条件处理用户输入验证

时间:2014-04-27 11:11:09

标签: clojure

我编写了一个游戏服务器,并且必须检查来自用户的消息是否正确且有效。这意味着它们必须具有正确的语法,符合参数格式并且语义正确,即符合游戏规则。

我的目标是拥有一种富有表现力的功能性方法,而不会抛出允许尽可能好的可组合性的异常。

我知道其他类似的问题,但他们要么引用我不喜欢的{:pre ..., :post ...},因为一旦抛出异常,只能处理字符串化的信息,或者引用一般我不喜欢的异常处理因为Clojure应该能够做这种任务,或者他们用例如Haskell的monadic风格也许Monadàla(-> [err succ])我也不喜欢,因为Clojure应该能够在不需要Monad的情况下处理这类任务。

到目前为止,我使用cond作为前置条件检查器和错误代码,然后我将其发送回发送请求的客户端:

(defn msg-handler [client {:keys [version step game args] :as msg}]
  (cond
    (nil? msg)                     :4001
    (not (valid-message? msg))     :4002
    (not (valid-version? version)) :5050
    (not (valid-step?    step))    :4003
    (not (valid-game-id? game))    :4004
    (not (valid-args?    args))    :4007
    :else (step-handler client step game args)))

和类似......

(defn start-game [game-id client]
  (let [games   @*games*
        game    (get games game-id)
        state   (:state game)
        players (:players game)]
    (cond
      (< (count players) 2) :4120
      (= state :started)    :4093
      (= state :finished)   :4100
      :else ...)))

另一种方法是编写一个宏,类似于defn{:pre},但不是抛出AssertionError抛出ex-info一张地图,而是再次:反对例外投掷。

0 个答案:

没有答案