我已经写了一些代码来暂停某个课程的注册。一个课程可能有多个演示文稿。
module Enrolments
class Suspend
attr_reader :enrolment, :responses, :comment, :user_id
attr_writer :event_service, :suspend_enrolment_presentation_service
def initialize
@responses = []
end
def call(enrolment, user_id, comment)
@enrolment = enrolment
@user_id = user_id
@comment = comment
suspend_enrolment_presentations
if all_enrolment_presentations_suspended?
suspend_enrolment
raise_suspended_enrolment_event
create_enrolment_comment
end
end
private
attr_reader :response
def suspend_enrolment_presentations
enrolment.enrolment_presentations.each do |ep|
@responses << suspend_enrolment_presentation_service.call(ep)
end
end
def all_enrolment_presentations_suspended?
@responses.all?{ |r| r[:success] }
end
def suspend_enrolment
enrolment.status = 'Suspended'
enrolment.save
end
def raise_suspended_enrolment_event
event_service.call(enrolment)
end
def create_enrolment_comment
EnrolmentComment.create(comment: comment, user_id: user_id, enrolment_id: enrolment.id)
end
def event_service
@event_service ||= Events::Outgoing::Enrolments::SuspendedEnrolment.new
end
def suspend_enrolment_presentation_service
@suspend_enrolment_presentation_service ||= Enrolments::EnrolmentPresentations::Suspend.new
end
end
end代码是相当直接的。它有两个依赖项,它们在测试时通过attr_writers注入,否则在访问时被实例化。
我听过/读过许多关于回调的问题。这段代码的问题在于,如果我只想暂停注册,而不想引发事件或创建注释,我就不能。一些解决方法是使用装饰模式,或者我想我可以组合和对象所有的服务,并管理其中的所有内容。
我真的在我的代码中为SRP和好的设计而奋斗。我非常感谢任何关于如何改进这段代码的意见。我是否应该将代码提取到更高的抽象级别,并将其处理得更高一级呢?如果运行一段代码取决于另一段代码的传递怎么办?如果我要将它提取出来,它将在我的控制器中着陆,这是我所能达到的高度,除非我随后将它提取到一个表单对象中。
发布于 2015-08-05 06:14:25
在我看来,原来的课正在打破SRP,所以我决定把这个班分成两个班。一个处理当暂停发生时需要发生的事情的协调。这允许我只包含注册者的实际暂停逻辑::挂起和任何其他必需的回调都被放入协调器。这样,每个类都应该只有一个改变的理由。
module Enrolments
class SuspendCoordinator
attr_reader :enrolment, :comment
attr_writer :event_service, :suspend_enrolment_service
def call(enrolment, comment)
@enrolment = enrolment
@comment = comment
if suspend_enrolment
raise_suspended_enrolment_event
create_enrolment_comment
end
end
private
attr_reader :responses
def suspend_enrolment
suspend_enrolment_service.call(enrolment)
end
def raise_suspended_enrolment_event
event_service.call(enrolment)
end
def create_enrolment_comment
EnrolmentComment.create(comment: comment, user_id: RequestRegistry.current_user.id, enrolment_id: enrolment.id)
end
def suspend_enrolment_service
@suspend_enrolment_service ||= Enrolments::Suspend.new
end
def event_service
@event_service ||= Events::Outgoing::Enrolments::SuspendedEnrolment.new
end
end
end
module Enrolments
class Suspend
attr_reader :enrolment, :responses, :comment, :user_id
attr_writer :suspend_enrolment_presentation_service
def initialize
@responses = []
end
def call(enrolment)
@enrolment = enrolment
suspend_enrolment_presentations
suspend_enrolment if all_enrolment_presentations_suspended?
end
private
attr_reader :response
def suspend_enrolment_presentations
enrolment.enrolment_presentations.each do |ep|
@responses << suspend_enrolment_presentation_service.call(ep)
end
end
def suspend_enrolment
enrolment.status = 'Suspended'
enrolment.save
end
def all_enrolment_presentations_suspended?
@responses.all?{ |r| r[:success] }
end
def suspend_enrolment_presentation_service
@suspend_enrolment_presentation_service ||= Enrolments::EnrolmentPresentations::Suspend.new
end
end
endhttps://codereview.stackexchange.com/questions/98674
复制相似问题