对於 domain 内的 aggregate,有以下的原则我们会遵守
假设现在的 domain 是一个班级,一个班级底下会有一个老师和很多学生
设计出来的 aggregate 大致上会长这样
# 班级 class.rb
class Class < Boxenn::Entity
def self.primary_keys
%i[grade name]
end
# 年级
attribute :grade, Types::Coercible::Integer
# 班级名字
attribute :name, Types::String.enum('甲', '乙', '丙', '丁')
# 老师
attribute :teacher, Entities::Teacher.optional.default(nil)
# 学生
attribute :students, Types::Array.of(Entities::Student).default([].freeze)
def class_people_count
teacher.present? ? students.size + 1 : students.size
end
end
# 老师 teacher.rb
class Teacher < Boxenn::Entity
def self.primary_keys
[:id_number]
end
# 身分证字号
attribute :id_number, Types::Coercible::String
# 个人资料
attribute :profile, Entities::PersonProfile
end
# 学生 student.rb
class Student < Boxenn::Entity
def self.primary_keys
[:id_number]
end
# 身分证字号
attribute :id_number, Types::Coercible::String
# 学生编号
attribute :student_number, Types::Coercible::String.optional.default(nil)
# 个人资料
attribute :profile, Entities::PersonProfile
end
# 个人资讯 (value object) person_profile.rb
class PersonProfile < Dry::Struct
# 名字
attribute :name, Types::Coercible::String
# 性别
attribute :gender, Types::Symbol.enum(:male, :female, :other).optional.default(nil)
# 生日
attribute :birthday, Types::Date.optional.default(nil)
def age
today = Time.zone.today
gap = today.year - birthday.year
gap = gap - 1 if (
birthday.month > today.month or
(birthday.month >= today.month and birthday.day > today.day)
)
gap
end
end
补充上一篇关於 dry-struct 的用法:
profile = PersonProfile.new(name: 'Tom')
profile = profile.new(gender: :male)
Array
,那个属性是 mutable 的,如果想让所有属性都保持 immutable,则需要给予 default 值并 freeze attribute :numbers, Types::Array.of(Types::Integer).default([].freeze)
Aggregate 是我们在 DLL 中主要操作的物件,因此它的设计会直接影响到 code base 的依赖关系。
下一篇会来介绍 Boxenn 是如何实作 repository pattern,并通用化到不同的外部介面。
<<: Day 11 : PHP - 如何将HTML的内容传送到PHP?POST和GET又该如何选择?
更改 state 有其风险,State manipulation 有赚有赔,更改前应详阅官方文件说明...
昨天我们已经成功建立资料库了,今天要做的是将资料存进资料库并且让TableView能马上更新资料库里...
以下将介绍几个实用的切版学习资源与工具 e Odin Project(完整规划和复合式学习) 这是一...
函式没办法使用其他函式中的变数 #include <stdio.h> #include ...