如何设计FootballMatch足球比赛领域实体模型?哪种方案更合适?
你的判断没错,方案三是三个选项里最优的,结合你的需求可以再做少许优化,以下是三个方案的具体优劣分析:
方案一的核心问题
把比分存为字符串属于典型的用非结构化类型存储结构化数据,后续要做比分对比、统计某队单场进球数这类操作时,每次都需要拆分字符串,还要额外处理格式异常,容错成本极高。而且球队字段和比分字段完全独立没有绑定关系,后续如果调整FirstTeam/SecondTeam的赋值顺序但忘了同步修改Score,就会出现数据完全不一致的问题,排查成本很高。
方案二的核心问题
足球比赛固定只有2支参赛队的场景下,用集合存储球队完全是过度设计。首先IEnumerable本身没有长度约束,语法层面没法保证集合里一定只有2个元素,极端情况出现空元素、多元素都会直接导致业务报错。其次比分和球队的对应完全依赖索引顺序,没有任何显式约束,后续维护代码的人很难第一时间搞懂Teams[0]和Teams[1]的含义,很容易出现顺序搞反的bug。
方案三的优势和优化点
你设计的TeamPlay中间实体把球队、所属比赛、进球数做了强绑定,从根本上避免了球队和比分不匹配的问题,强类型存储进球数也不用做额外的字符串解析,业务逻辑更健壮。后续如果需要扩展比赛的球队维度数据(比如红黄牌数、射正数、控球率等),直接往TeamPlay类里加字段即可,扩展性远高于前两个方案。
可以补充两个小优化:
- 在
FootballMatch类里加一个只读的Score属性,需要展示比分的时候直接调用,避免手动拼接出错:
public string Score => $"{FirstTeam.Goals}-{SecondTeam.Goals}";
- 你现有
Team类的AttendedMatches属性可以调整为存储IEnumerable<TeamPlay>类型,这样不需要再到比赛实体里比对球队就能直接拿到该队对应场次的进球、参赛数据,查询效率更高。另外注意你现有代码里的FootbalMatch拼写少了一个字母l,应该是FootballMatch,避免后续引用报错。
内容的提问来源于stack exchange,提问作者Markus Aurelios
相关产品推荐
相关产品推荐

