首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阿克卡演员计算足球联赛排名

阿克卡演员计算足球联赛排名
EN

Code Review用户
提问于 2017-03-15 19:58:40
回答 1查看 85关注 0票数 3

我对Scala / Akka很陌生,这是我第一次尝试写一个演员。

我想要完成的任务是:给定一个足球比赛序列,根据足球的一般规则生成一个排名(胜利者得到3分,输家得到0分,平局时每个人得到1分)。

以下是我目前的角色演员:

代码语言:javascript
复制
package soccerLeague.akka

import akka.actor.Actor
import soccerLeague.common.{LeagueRules, MatchResult, TeamWithPoints}

// Stateful Ranker actor that maintains a rank.
// The rank gets updated every time a MatchResult message is received.
class RankerActor(rules: LeagueRules) extends Actor {

  private var rank: Seq[TeamWithPoints] = List()
  private var rankMap = Map[String, Int]()

  def receive = {
    case MatchResult(team1, score1, team2, score2) => {
      updateRank(MatchResult(team1, score1, team2, score2))
      sender ! rank
    }
    case Message("getRank") => {
      sender ! rank
    }
  }

  private def updateRank(matchRes: MatchResult): Unit = {

    def calcDeltaPoints(score1: Int, score2: Int): Int = {
      if(score1 == score2) rules.drawScore
      else if(score1 > score2) rules.winScore
      else rules.lossScore
    }

    val newPoints1 = rankMap.getOrElse(matchRes.team1, 0) + calcDeltaPoints(matchRes.score1, matchRes.score2)
    val newPoints2 = rankMap.getOrElse(matchRes.team2, 0) + calcDeltaPoints(matchRes.score2, matchRes.score1)

    rankMap += (matchRes.team1 -> newPoints1, matchRes.team2 -> newPoints2)

    // Sort by score, in reverse order (i.e. the team with most points is first).
    // Teams that have the same score are sorted in alphabetical order.
    // TODO: this *can* be improved by only moving around the two teams that are changing.
    rank = rankMap.toSeq
      .map { case (t, s) => new TeamWithPoints(t, s) }
      .sortBy { case TeamWithPoints(team, points) => (-points, team) }
  }

}

我有几门辅助性案例课:

代码语言:javascript
复制
case class MatchResult(team1: String, score1: Int, team2: String, score2: Int)
case class LeagueRules(winScore: Int, drawScore: Int, lossScore: Int)
case class TeamWithPoints(team: String, points: Int)
  • 有什么方法可以使这段代码更好、更地道呢?
  • 我如何避免解构MatchResult (在receive方法中),然后当我想将它传递给updateRank方法时,再重新构造它?
EN

回答 1

Code Review用户

发布于 2017-03-15 20:40:39

首先,您可以尝试向Actor发送命令,而不是名词(源: Actor模型的反应性消息传递模式)。

  1. 将命令放入Actor的伴生对象中。
  2. 用过去式命名命令。
  3. 删除“文字匹配”getRank(消息)并创建一个命令(类型-safet)来处理该方法。

有关命名命令的信息,请参阅此线程。https://stackoverflow.com/questions/12510535/naming-convention-for-commands-events

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/157857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档