Erlang/Elixir Elixir 用 sum type 建模

chenge · 2021年05月09日 · 最后由 linlinda 回复于 2023年11月03日 · 314 次阅读

昨天群里听网友介绍了这个 sum type 的博客,跟大家分享一下。

场景是设计一个双人比赛游戏,下面展示两种方案

原来的方案

defmodule Game do
  defstruct [:status, :players, :winning_player]

  @type status :: :not_started | :in_progress | :finished

  @type t :: %__MODULE__{
    status: status(),
    players: {Player.t(), Player.t()} | nil,
    winning_player: Player.t() | nil
  }
end

这个方案容易产生出现非法状态,导致 bug,接下来改进一下设计。

sum type 模式

defmodule Game do
  defstruct [:status]

  @type players :: {Player.t(), Player.t()}
  @type status :: :not_started | {:in_progress, players()} | {:finished, Player.t()}

  @type t :: %__MODULE__{status: status()}
end

更详细的内容,参考原来英文博客 Better domain modeling in Elixir with sum types

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号