昨天群里听网友介绍了这个 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,接下来改进一下设计。
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