Elixir游戏服设计五

在《Elixir游戏服设计一》里提到,按照系统功能划分成app要保证原子性很难,

现在想想也没那么难。保证原子性,无非就是需要某个单点去完成操作。那么选择玩家进程去做原子性工作就可以了。

比如要重置某个任务,需要花费金币和背包里某个物品,那么大概的逻辑是这样的。在玩家进程里

def reset_task(task_id) do
    {need_gold, need_item} = Task.reset_need
    with
        :ok = gold_enough(need_gold)    #使用玩家进程的数据
        :ok = BagServer.item_enough(need_item)  #使用背包进程的数据
    do
        {:ok, new_state} = cost_gold(need_gold)  #使用玩家进程数据
        :ok = BagServer.cost_item(need_item)    #使用背包进程数据
        TaskServer.reset(task_id)               #使用任务进程数据
    end
end

只不过说这样做以后,发觉Bag和Task进程做的工作也不多,不像玩家进程那么活泼。

如果想让Bag和Task有更多职责,你需要把reset_task之类的

操作直接交由他们做,比如如下。

def reset(task_id) do
    need = {need_gold, need_item} = reset_need
    with
        :ok = PlayerServer.gold_enough(need_gold)
        :ok = BagServer.item_enough(need_item)
    do
        :ok = PlayerServer.cost(need)  ## 这里是原子的操作,同上面一样操作cost
        reset(task_id)
    end
end

但需要分清楚一些操作还是要交由某个单点去做(比如玩家进程),费心去理清这点,显得烦人。

而且每个模块需要知道很多其他模块,比如TaskServer需要使用BagServer,这也是一个糟糕之处。

这么一想,我还真找不到要划分成应用(进程那种)的理由了;一个库应用,甚至于一个模块就可以满足需求。

原文地址:https://www.cnblogs.com/rubyist/p/5542361.html