介绍
这篇文章是关于一位热爱麻将的新手工程师,他模仿他所看到的并试图将点棒(如麻将中的货币)作为价值对象。如果您能在空闲时间阅读它,我会很高兴。
首先,我想简单说一下“首先什么是值对象?”
(*是在有麻将知识的前提下写的.如果您什么都不知道,我建议您只阅读“什么是值对象?”部分。 )
什么是值对象
什么是值对象一种将值表示为类的设计模式是。
更详细地说,应用中经常使用的金额、日期和电话号码等值被视为类,对值本身及其行为进行集体管理,同时确保每个值在初始化阶段的正常性是。
例如,如果将金额视为单纯的 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