[Day12] Boxenn 实作 Record Mapper 与 Factory

建议搭配之前的 sequence diagram 一起服用!

Dry Initializer

在进到 Record Mapper 和 Factory 之前,先来介绍一下 dry-initializer,他替我们省略掉 constructor (在 ruby 中是 initialize)中赋值给实例变数(instance variable)的工作,在 spec 中这样的特性让我们可以简单的替换掉跟外部依赖的 class。

require 'dry/initializer'

class User
	extend Dry::Initializer

	param  :name,  default: proc { nil }
	option :age, default: proc { nil }
end

user = User.new 'Tom', age: 23
user.name # => 'Tom'
user.age # => 23

Q: 放在 initialize 的参数和放在 method 的参数有甚麽不同?

我们放在 initialize 的参数都是属於工具或模组化的 class,通常在 spec 中都会把这些 class 抽换掉,而 method 传入的才是那个 method 有用到的参数。

Record Mapper

Record Mapper的职责是把 aggregatehash 转成对应 db schema key 的 hash,选择转成 hash 的原因是 hash 是 ruby 的 base type,如此一来便可以让 mapper 通用化到不同的外部资源(ORM、Database、其他 gem 等等)

class Order < Boxenn::Repositories::Mapper
  def build(hash)
    # key 是对应到 DB schema columns name,而 value 则是 entity 的 attibutes name
    {
      custom_serial_number: hash[:serial_number],
      status: hash[:status],
      created_at: hash[:puchased_at],
      comment: hash[:comment],
    }
  end
end

Factory

Factory 的职责跟 Record Mapper 刚好恰恰相反,是把 source 转成 aggregate ,而在Boxenn::Repositories::Factory 中定义的介面也是 build,除此之外还需要使用 dry-initializer 指定 entity。

这边的 Factory 不是在 DDD 或 clean architecture 中的 factory,单纯只是一个转换器,名字是为了与 record mapper 作区别。

class Order < Boxenn::Repositories::Factory
	# 指定 entity 让 factory 和 repository 使用
  param :entity, default: -> { Entities::Order }

  def build(source_object)
    entity.new(
      serial_number: source_object.custom_serial_number,
      status: source_object.status,
      puchased_at: source_object.created_at,
      comment: source_object.comment,
    )
  end
end

下一篇会进一步扩充 record mapper,使每次在建立基础设施时更加快速。


<<:  【Day27】音乐情绪与乐理

>>:  自动化 End-End 测试 Nightwatch.js 之踩雷笔记:上传档案

[Day 01] 前言

大家好,我是来自台北教育大学玩游所的硕士生 May,在大学接触到如何写网页後,就毅然踏入了前端这个大...

菜鸟新人第七十五天

当小菜渣也好一阵子了, 来记录一下 铁人赛结束後,也顺利的录取心目中满意的公司 十一月报到後就开始当...

[Day 29] Optimize Images

取自 Artifact Austin: Leaving Pixels Behind - Todd ...

[Day21]Laravel目录结构

Laravel目录结构 先来说说各个目录及资料夹里面放置档案,并没有强制规定 根目录 app目录 a...

[Day20] Laravel起步走

Laravel起步走 Laravel是一个MVC架构的PHP框架,分别是model(资料处理),co...