[Ruby] 我试图让麻将点棒成为价值对象?

寻技术 Ruby编程 2023年07月12日 101

介绍

这篇文章是关于一位热爱麻将的新手工程师,他模仿他所看到的并试图将点棒(如麻将中的货币)作为价值对象。如果您能在空闲时间阅读它,我会很高兴。
首先,我想简单说一下“首先什么是值对象?”
(*是在有麻将知识的前提下写的.如果您什么都不知道,我建议您只阅读“什么是值对象?”部分。 )

什么是值对象

什么是值对象一种将值表示为类的设计模式是。
更详细地说,应用中经常使用的金额、日期和电话号码等值被视为类,对值本身及其行为进行集体管理,同时确保每个值在初始化阶段的正常性是。

例如,如果将金额视为单纯的 int 类型变量,则在金额变量中输入负值,或者在金额变量中添加其他 int 类型(例如“销售额”)。虽然可能发生,但您可以通过将金额转换为值对象来防止此类错误。
此外,对于您希望在价值中具有的行为,例如税收计算方法,可以具有高度的凝聚力(*1)。

如上所述,它是一个有用的值对象,但需要注意的是,在实现它时必须实现以下特性。

  • 值是不可变的
  • 可更换
  • 按值相等比较

* 参考资料

  • “我想增加应用服务的凝聚力”(*1 关于凝聚力)
  • 用好/坏代码介绍设计学习](关于值对象)
  • 领域驱动设计简介](关于值对象)

点条对象

示例代码

# frozen_string_literal: true

#
# 点棒
#
class Counter
  include Comparable

  attr_reader :point

  # ゲーム開始時の点棒
  DEFAULT_POINT = 
  # 順位点処理として、4位3位2位がそれぞれ1位に対して支払う点棒(オカ)
  OKA_POINT = 
  # 順位点処理として、4位が1位に支払う点棒(ウマ)
  UMA_POINT1 = 
  # 順位点処理として、3位が2位に支払う点棒(ウマ)
  UMA_POINT2 = 

  def initialize(point = DEFAULT_POINT)
    # 最小の点棒が100点なので、100で割り切れない値は不正とする
    raise ArgumentError, '不正な点棒です' if point %  != 

    @point = point
    freeze # 不変にする
  end

  # 値オブジェクトは不変なので、オブジェクトを交換する形で足し算を実装する
  def add(other)
    Counter.new(point + other.point)
  end

  # 引き算も同様
  def subtract(other)
    Counter.new(point - other.point)
  end

  # 値の等価性で比較する
  def <=>(other)
    point <=> other.point
  end

  # 着順に応じて順位点処理を行う
  def add_rank_point(rank)
    case rank
    when 
      rank_point =  UMA_POINT1 + OKA_POINT * 
    when 
      rank_point =  UMA_POINT2 - OKA_POINT
    when 
      rank_point = -UMA_POINT2 - OKA_POINT
    when 
      rank_point = -UMA_POINT1 - OKA_POINT
    else
      raise ArgumentError, '不正な着順です'
    end
    Counter.new(point + rank_point)
  end
end

示例代码详细信息

attr_reader

我希望这个值是不可变的,所以我用attr_reader 实现了它,它只定义了setter。

initialize

由于麻将棒只存在到第 100 位,因此对于不能被 100 整除的参数会引发错误。在实现数量对象等时,我认为在初始化中类似地验证负值是一个好主意。
还有freeze 使其不可变。

<=>

它是为了比较值是否相等而编写的。
如果没有这个描述,即使是具有相同值的对象也会被判断为假。

Counter.new() == Counter.new()
#=> false

# <=>メソッド定義後
Counter.new() == Counter.new()
#=> true

add_rank_point

它描述了根据到达顺序的排序点处理。值对象的伟大之处在于,您可以像这样一起描述值本身和值的行为。
不看细节也没关系。

想法

在实践中我从来没有机会写过一个值对象,所以这是我第一次写它,但它很有趣。如果您认为应该做得更好,请发表评论。
我用接收对象的简单形式实现了加减法,但是在麻将中,移动分数是由音译和标记决定的,所以最好接收音译、标记和存款作为参数并计算得分。我本来可以做到的。如果有机会,我会写的。
M联赛也开放了!让我们提高麻将的热度?

原创声明:本文系作者授权九品源码发表,未经许可,不得转载;

原文地址:https://www.19jp.com/show-308628175.html

关闭

用微信“扫一扫”