8 稍微重构一下下,一点就好

昨天我们按照要改动的事项一个一个的做了出牌的方法
今天来调整一下

  def play_card(pid, :host, card) do
    GenServer.cast(pid, {:play_card, :host, card})
  end

  def handle_cast({:play_card, :host, card}, game) do
    %{host: host} = game

    # 从 hand 里面拿掉一张 1 
    new_hand = host.hand -- [card]

    # 把 1 加在 host 的 desk 里面
    new_desk = host.desk ++ [card]

    # 组成新的 host 来替换旧的
    new_host = Map.merge(host, %{hand: new_hand, desk: new_desk})

    # 组成新的 game 来替换旧的
    new_game = Map.replace(game, :host, new_host)

    # 让 process 使用新的 game
    {:noreply, new_game}
  end

首先我们先解决 guest 还不能出牌的问题,
其实就复制一份 handle_cast({:play_card, :host, card}, game) 方法
再把里面的 host 都改成 guest 就可以了,但是这样变超长,
再更改之前先讲一下同名方法。

elixir 同名方法

elixir 可以有同名方法,呼叫的时候会从上面开始 pattern matching 变数,
举例来说

defmodule Lunch do
  def eat("apple") do
  end

  def eat("cake") do
  end

  def eat(other) do
  end
end

如果我呼叫 Lunch.eat("apple")
就会对应到第一个

如果我呼叫 Lunch.eat("pie")
因为前两项都不符合,所以会到第三个,并把 other 变数赋予 "pie"


我们试着 dry 一点,一点就好

  def handle_cast({:play_card, :host, card}, game) do
    %{host: host} = game
    new_hand = host.hand -- [card]
    new_desk = host.desk ++ [card]
    new_host = Map.merge(host, %{hand: new_hand, desk: new_desk})
    new_game = Map.replace(game, :host, new_host)
    {:noreply, new_game}
  end
  def handle_cast({:play_card, :guest, card}, game) do
    %{guest: guest} = game
    new_hand = guest.hand -- [card]
    new_desk = guest.desk ++ [card]
    new_host = Map.merge(guest, %{hand: new_hand, desk: new_desk})
    new_game = Map.replace(game, :guest, new_host)
    {:noreply, new_game}
  end

我们来做一个方法把重复的地方拉出来

  def handle_cast({:play_card, :host, card}, game) do
    %{host: host} = game
    new_host = play_card_helper(host)
    new_game = Map.replace(game, :host, new_host)
    {:noreply, new_game}
  end
  def handle_cast({:play_card, :guest, card}, game) do
    %{guest: guest} = game
    new_guest = play_card_helper(guest)
    new_game = Map.replace(game, :guest, new_host)
    {:noreply, new_game}
  end
  defp play_card_helper(data) do
    new_hand = data.hand -- [card]
    new_desk = data.desk ++ [card]
    Map.merge(data, %{hand: new_hand, desk: new_desk})
  end

再把那些等号拆掉

  def handle_cast({:play_card, :host, card}, game) do
    %{host: host} = game
    {:noreply, Map.replace(game, :host, play_card_helper(host, card))}
  end
  def handle_cast({:play_card, :guest, card}, game) do
    %{guest: guest} = game
    {:noreply, Map.replace(game, :guest, play_card_helper(guest, card))}
  end
  defp play_card_helper(data, card) do
    Map.merge(data, %{hand: data.hand -- [card], desk: data.desk ++ [card]})
  end

我们可以再 pattern matching 方法的过程,直接从 game 里面取用 %{host: host}

  def handle_cast({:play_card, :host, card}, %{host: host} = game) do
    {:noreply, Map.replace(game, :host, play_card_helper(host, card))}
  end

  def handle_cast({:play_card, :guest, card}, %{host: host} = game) do
    {:noreply, Map.replace(game, :guest, play_card_helper(guest, card))}
  end

  defp play_card_helper(data, card) do
    Map.merge(data, %{hand: data.hand -- [card], desk: data.desk ++ [card]})
  end

好像可以改的更好,至少更好读一点,比起这样塞成一行
但是先这样吧,还有很多功能要做

如果是以别人好读懂的方向来调整,你会怎麽做呢?

(别人就是未来的自己哈哈)


<<:  [第七只羊] 迷雾森林舞会前夕 建立使用者关联

>>:  RISC V::中断与异常处理 -- 中断篇

第26天~用电灯的照片代表连到感应器

开新档案- 布置一下design- 放入两张电灯照片当开关- Firebase网站连线- packa...

[Day15]-类别2

类别继承 定义:可以继承父类别所有的公有方法与属性,在子类别就不用重新设计 基於保护原则,外部是不...

day6 阿伯出事啦 exception

Coroutine支援kotlin一般的Exception处理 try/catch/finally,...

【Day13】在Ezyme上装上相对应版本的适配器(Adapter)吧´・ᴗ・`

前面我们有大概提到Enzyme的优点及作用~ 这篇我们要直接来安装Enzyme和导入Enzyme来供...

[Java Day29] 6.6. 抽象类别

教材网址 https://coding104.blogspot.com/2021/06/java-a...