Ruby on Rails中的关注点是否取代了MVC中的服务类



我是RubyonRails的新手。RubyonRails来自C#和Java背景,看起来很奇怪,但同时也很有趣。这几乎就像是从一个基于类的面向对象世界到JavaScript的原型概念,甚至到一种函数语言。

无论如何,在传统的C#或JavaMVC应用程序中,我倾向于保持我的模型和控制器尽可能干净,将业务逻辑提取到服务类中。我的模型只是POCO/POJO(最多有一些计算字段和验证)。我的控制器只处理传入的请求(严重依赖于依赖项注入),然后返回一个视图或JSON。

然而,我在RoR世界中没有看到任何明确的模式。有些人倾向于将他们所有的业务逻辑都放入控制器中,有些人则将其放入模型中(使用ActiveRecords,这有点道理,尽管我不喜欢)。

然后是"关注"的概念。它们是提取我的业务逻辑而不是使用服务的正确位置吗?如果是的话,你能提供一个Concers正确使用的例子吗?我仍然很难理解模块的概念(它们更多的是名称空间,还是接口)?正如一开始所说的,Ruby对我来说就像是一个全新的星系

这个问题可能会引起一些争议,因为它会带来很多个人偏好。然而,这是我的看法。

首先,关注点不能取代服务类。关注是管理你的混合体的一种干净而巧妙的方式。如果您是Ruby的新手,那么mix-ins基本上是将实例和/或类方法注入到现有类中的一种方式。例如,给定以下类:

class EvilRobot < ActiveRecord::Base
def destroy(target)
...
end
end
class OrneryTeenAger < ActiveRecord::Base
def destroy(target)
...
end
end

你可以用来干燥代码

require 'active_support/concern'
module EvilTools
extend ActiveSupport::Concern
included do
def destroy(target)
...
end
end
end
class EvilRobot < ActiveRecord::Base
include EvilTools
end
class OrneryTeenAger < ActiveRecord::Base
include EvilTools
end

我认为绝大多数Rails开发人员,包括我自己,都喜欢胖模型、瘦控制器的设计。不过,到底有多胖是个品味问题。如果功能在逻辑上不适合模型,或者提取到引擎或gem中,我也倾向于将它们转移到lib下的类中。

我认为jpgeek反应是答案的一部分。这是向服务对象的大量移动,以清理胖模型或大型控制器的操作。只需创建一个应用程序/服务文件夹并创建服务类,如:

class TargetDestructionService
def initialize(shooter, target)
@shooter = shooter
@target = target
end

def execute
#Lot of code that causes the destruction of the target.
end
end

然后在你的模型或控制器中,你会调用:

TargetDestructionService.new(EvilRobot.new, Human.new).execute

这里有一篇关于它的好文章:https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services

最新更新