call
dry-monads
的特性处理预期及非预期错误use case
内利用 steps
拆解每一个步骤,让程序码易读dry-initializer
让依赖的元件可被替换,进而使程序码易测试require 'dry/monads/all'
require 'wisper'
require 'dry/initializer'
module Boxenn
class UseCase
extend Dry::Initializer
include Wisper::Publisher
include Dry::Monads
include Dry::Monads::Do
def call(*args)
Success(yield(steps(*args)))
rescue Dry::Monads::Do::Halt
raise
rescue StandardError => e
Failure.new([e], trace: e.backtrace.first)
end
protected
def steps
raise NotImplementedError
end
end
end
这边用建立订单当作例子,假设建立订单需要验证订单及发送行销信给客户。
class CreateOrder < Boxenn::UseCase
option :repo, default: -> { OrderRepository.new }
option :marketing_client, default: -> { Marketing::Client.new }
def steps(params:)
order = build_order(params)
yield valid_order(order) # 因为回传是 Dry::Monads::Result 所以需要 yield
create_order(order)
send_marketing_email(order.serial_number)
end
private
def build_order(params)
OrderEntity.new(params)
end
def valid_order(order)
# 假设 order entity 有个 method valid? 会回传 Bool 告知是否合法
return Success() if order.valid?
Failure('Invalid Order')
end
def create_order(order)
repo.save(order)
end
def send_marketing_email(serial_number)
marketing_client.send_purchase_email(order_serial_number: serial_number)
Success() # 最後一个 call 的 method 需要回传 Dry::Monads::Result
end
end
use_case = CreateOrder.new
use_case.call(params: params) # => Success()
下一篇将说明 domain 间的依赖关系,以及 pub-sub pattern 的使用。
<<: [day19]Vue实作-登入功能实作串接後端API(上)调整bootstrapvue
>>: Day_22: 让 Vite 来开启你的Vue 之 跨元件响应式资料的处理
说明 晚点补 程序码 #include <stdbool.h> #include <...
今日来延续昨日没有写完的全域变数。 Error Handlin //里面可以做一些条件判断,如果为f...
我们前面已经了解了事件绑定与事件冒泡了,但是使用 物件元素.绑定事件 有不方便的地方 只能同时为一...
大家好,大家都叫我西瓜。因为想转职写游戏,而游戏中会让人第一个想到、也是能在第一瞬间吸引人的就是画面...
接着要示范如何用 Eloquent 建立多对多关联的查询,目标帮目前的 Todo 建立 Tag 标签...