#world #cup #live #scoreboard #scores #board #following

scoreboard_world_cup

用于追踪世界杯当前比赛结果的简单评分板

2个版本

0.1.1 2023年11月8日
0.1.0 2023年11月8日

#2#scoreboard

MIT 许可证

1MB
637

包含 (WOFF字体,400KB) NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2,(WOFF字体,135KB) FiraSans-Medium-8f9a781e4970d388.woff2,(WOFF字体,130KB) FiraSans-Regular-018c141bf0843ffd.woff2,(WOFF字体,82KB) SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2,(WOFF字体,77KB) SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,(WOFF字体,45KB) SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 和更多

评分板

编码练习

开发一个新的实时世界杯评分库,显示所有正在进行的比赛及其比分

要求

  1. 必须是库实现
  2. 使用内存存储解决方案
  3. 使用TDD,注意面向对象设计、Clean Code和SOLID原则
  4. 实现基本API
    • 开始比赛。假设初始比分“0-0”,应捕获两个参数:主队和客队
    • 更新比分。应接收一对绝对比分:主队比分和客队比分
    • 结束比赛。从评分板中移除正在进行的比赛
    • 获取摘要。返回所有当前比赛,按总比分排序,总比分相同的按最近开始时间排序

假设

  1. 不期望特定编程语言。为了学习目的,此项目将使用Rust
  2. 未提及线程安全性。它被认为是“最好有的”功能
  3. 一支球队在给定时间内只能参加一场比赛。例如,如果目前正在举行洪都拉斯和哥斯达黎加之间的比赛,这两支球队都不能出现在新创建的比赛
  4. 在所有API调用中,“主队”始终位于“客队”之前。如果球队的顺序对于操作不正确,则返回错误
  5. 获取当前结果摘要将比其他所有API函数更频繁地使用。这将影响优化选择

进度

基本要求

要求 状态 注释
1. 库 作为一个独立的Rust库crate开发
2. 存储 使用标准的Vec向量集合。有关更多评论,请参阅“可能的附加功能 -> 优化”
3. TDD 在一定程度上遵循TDD。大多数函数都很小,可以首先为第一个测试编写最终正确的版本,然后添加其他边界情况
4. API 公共ScoreBoard结构和其方法
4.1. 开始 ScoreBoard.start_game(home_team_name,away_team_name)
4.2. 更新 ScoreBoard.更新得分(home_team_name,主场得分,away_team_name,客场得分)
4.3. 完成 ScoreBoard.完成比赛(home_team_name,away_team_name)
4.4. 总结 ScoreBoard.获取总结()

额外功能

功能 状态 注释
队伍独特性 start_game(team1, team2)如果任一队伍正在比赛,则拒绝请求
线程安全 Rust编译器提供线程安全,除非涉及到严重的黑客攻击。在此仓库中没有unsafe代码

文档

该项目使用代码注释进行文档化

手动生成

运行此命令以生成文档并打开

cargodoc --open

在线

生成的文档可在GitHub Pages上找到,地址为daydreamest.github.io,或在crates.io

安装和使用

安装

  1. 安装Rust工作环境。使用带有所有默认选项的标准Rust安装指南
  2. 这应该也会安装Cargo,Rust默认包管理器
  3. 克隆此仓库

编译

移动到"scoreboard"目录并运行

>cargo build--release

第一次执行时,Cargo将下载依赖项(例如日志crate)。之后,库将被编译成二进制文件

scoreboard/target/release/libscoreboard.rlib

使用

作为Rust源代码

scoreboard.rs文件复制到您的项目中,并在需要的位置使用use导入模块

use scoreboard::*;

作为编译后的Rust库,使用rustc编译器

将编译后的libscoreboard.rlib文件复制到您的项目中,并在编译选项中添加一个标志

rustcmain.rs --externscoreboard=libscoreboard.rlib

作为cargo库

Cargo.toml文件中添加以下行,位于[dependencies]

scoreboard_world_cup= "0.1.1"

测试

要运行测试,请移动到"scoreboard"目录并运行

>cargo test

可能的其他功能

API

  1. 队伍名称在内部作为UTF-8字符串保留,没有进行广泛的验证。这允许像"AAAA - jskdfhgidsf","USA - U.S.A."或其他任何两个不同的字符串名称的匹配。一个很好的改进是创建一个枚举或字典,保留所有可用名称的列表,并对其进行验证
  2. update_score()非常难以使用,并允许任意更改得分。在足球中,得分的改变以量(通常称为“进球”)出现,因此应该有一个方法add_goal(team_name),它将提到的队伍的得分加1

优化

  1. 使用时间戳来验证哪个比赛先开始。这可能是一种过度行为,但比实现内部计数器更干净、更简单,但代价是CPU效率较低
  2. Vec用作数据容器。还有其他集合可用,但即使是Rust指南也建议坚持使用可靠的向量。可以考虑其他选择来提高效率,但它们需要进行性能分析和库的真实世界使用
  3. 每次添加、得分变化和删除数据后都会进行排序。排序可以移动到汇总显示方法中,这样在代码中“发生”的次数将只有一次,但这有一些缺点。
    • get_summary() 方法必须可变,并改变得分牌的状态,这不利于设计。
    • 作为替代,get_summary() 可以复制数据并在返回之前本地排序,但这会增加不必要的内存使用。
    • get_summary() 预计会被调用得比所有其他 API 函数的总和还要频繁,因此它必须快速简单。对大量并发比赛添加排序可能会严重影响时间。
    • 当前 sort() 的实现对于部分排序的集合或具有排序元素段的集合表现极佳(来源)。因此,它对现在使用的函数的影响应该很小,因为它们的更改仅适用于单个比赛,而其余集合保持排序。
  4. 可以考虑 Vecpush() 的替代方案,这些方案可能在某些情况下跳过排序。新创建的比赛具有最低的总得分和最新的时间戳,因此可能在 start_game() 上的排序可以省略,但这需要更多的分析。

问题

  1. “match” 是 Rust 中的一个关键字,因此在整个代码中使用“game”一词表示“两个队伍之间的比赛”。

依赖关系