RubyConf RubyConf China 2016 视频

huacnlee for Ruby China · 2016年10月28日 · 最后由 chihwoo 回复于 2016年11月25日 · 13813 次阅读
本帖已被管理员设置为精华贴

大家久等了,@jasl 已全部上传。

更多请访问 RubyConf China 2016 视频列表:

YouTube 有良好的品质,以及持久的存储,请自备翻墙工具观看(国内镜像请看 #5 楼)。

huacnlee 关闭了讨论。 10月28日 10:31
huacnlee 重新开启了讨论。 10月28日 10:31

现在社区工作各种规范,给管理员点个赞!👍

huacnlee RubyConf China 2016 会有录像吗? 提及了此话题。 10月28日 11:12

前排支持👍

8 楼 已删除

今年视频做的比去年好👍 👍 👍

棒棒哒👍 。。。

前排支持👍+1

很棒了!声音有点稍小。

huacnlee 将本帖设为了精华贴。 10月28日 16:28

亚飞的演讲很不错,但是视频跟 PPT 不同步啊

PPT 好像是按设定好的时间自动切换到下一页,和视频基本不同步,看着看着就到下个讲者的 PPT 😅

有 ppt 不同步的可以配合原版 ppt 看 https://ruby-china.org/topics/31164

我的这页 http://chloerei.com/rubyconfchina2016/#/4/4 如果不看动图是没有效果的。

下届务必用录屏方式。

薄荷网的微服务演讲里有一点我不是很明白 为什么要避免使用类方法的形式,而使用传入对象的方式呢?

类方法也可以继承,也可以复写

不知道有没有盆友能够提供下这么做的好处 thx

youtube 还能显示中文字幕,Google 真牛逼。

#23 楼 @huacnlee 报告一个 bug,@ 通知的人错了:

#23 楼 @huacnlee 另外再报告一个 bug,发帖的上传图片按钮,事件好像被绑定了多次,重现: 在本页面,点击任意一个其他链接,然后点击浏览器返回按钮,点击上传图片按钮,会弹出 2 次

好像 terry 前面有一个笑话暖场,那个没录像么?

#27 楼 @fsword terry 的主持都可以串起来作一集了,不知录了没。

#21 楼 @jicheng1014 我是薄荷的 vincent,欢迎探讨这个问题,😀

对于 ServiceObject,我认为使用类方法还是使用对象方法是两种看待(抽象)问题的方式。

# 类方法形式
class SuperService
   def self.call(params)
      # bla bla...
      # process it with params
   end
end

# call service
result = SuperService.call params
 # 对象方法形式
 class SuperService
    def initialize(params)
       @params = params
    end

    def call
       # bla bla...
       # process it with @params
    end
end

# call service
 service = SuperService.new params
 result = service.call 
  • 如果使用类方法,相当于把 ServiceObject 看做服务的提供者/管理者,每次服务过程,相当给服务提供者发送一个消息,请求相应结果。
  • 如果使用对象方法,相当于把 ServiceObject 看做是服务的模板,每次服务过程,需要先生成一个具体的服务对象,然后发消息给该服务对象,请求相应结果。

从代码上看起来,对象方法要比类方法要啰嗦一些,而且可能有的同学还担心使用对象方法性能要差一些,因为多生成了一个 service 对象,另外 params 还需要在对象中使用实例变量传递。

我们最初也使用类方法,后来才慢慢转变为使用对象方法。如果 service 很简单,使用类方法更简单直接的,但是当 service 变得复杂之后,我们发现使用对象方法的处理方式要好很多。

首先遇到的方法重构问题。当 service 逻辑变得复杂之后,在一个 call 方法里容纳所有的代码并不合适,这个时候要从中抽离方法,如果使用对象方法的话重构比较简单,剥离一些代码形成私有方法,然后在 call 方法中进行总调度就可以了。如果使用类方法的话,麻烦的是让类方法成为私有不那么直观,另外需要每个调用过程中传递所有参数。

其次是处理复用问题,对象方法形式的 ServiceObject 更容易处理。本质上对象方法形式的 ServiceObject 的方式更 OOP,所以可以很方便的使用一些面向对象的手法,包括继承和多态等等。类方法本质上是一种带了命名空间的全局方法,虽然类方法也能继承使用,但是相比对象方法的处理方式,没有那么优雅。

最后,对于有同学担心的性能问题,相比它带来的易扩展和优雅性,我觉得可以不值一提,一次 Rails request 生成的对象成千上万,一个极其轻量的 ServiceObject 对象生成可以忽略不计。

另外,每次都 new 一个 service 对象在 call 的方式确实有点累赘,本着 DRY 的原则,我们写一个 Servable module,只要 mix 这个 module,就可以使用简洁的直接 call 方式。

代码如下所示:

module Servable
   def call(*args)
     new(*args).call
   end
end

class SuperService
   extend Servable

   def initialize(params)
     @params = params
   end

   def call
      # bla bla ...
   end
end

# call service
result = SuperService.call params

The end.

#29 楼 @vincent 感谢如此详实的解释,下面是我自己的一些见解,希望对其他 RubyChina 朋友有用

关于类方法中进行抽象一部分函数私有化,我一般会这样处理

class Template
   class < self
    def seal
      puts "seal"
      invoke_private_method
    end

    private 
    def invoke_private_method
      puts "invoke_private_method"
    end
  end
end

我觉得实例化服务对象的最大好处就在于传参数只需要传一次参数,在有些时候会在一个动作里调用 service 里的几个方法的时候,这种方式比较轻松。比如下面的例子

def index
  service = UserService.new(current_user, params)
  service.notice_all_members
  service.start_user_docker
end

#30 楼 @jicheng1014 这些动作也可以做成 service 的实例方法,作为一个 service 的对象,可以按照顺序调用实例方法。我是这么理解的。

#30 楼 @jicheng1014 确实,包在 class 的 private 可以把类方法私有,但是这种方法和对象的私有方法相比,没法很简便的共享对象的状态,每个方法都要传递所有参数。

#32 楼 @vincent 今天我仔细听了下视频,你提到的跨服务数据访问中共享存储,举的例子是共享缓存,那是不是还有直接共享数据库的情况?比如每个服务都需要去验证用户的注册信息,是否是共享用户注册信息数据库?

#33 楼 @betterthornbird 感谢聆听!跨服务数据访问是实施微服务化后面临的一个麻烦问题,解决的方式多种多样,共享存储是一种变通方法。

微服务化的一个显著标志就是每个微服务都有自己独立的存储(包括数据库和缓存),独立开发和独立部署。每个微服务应该是独立的,通常情况一个服务需要使用另外一个服务的数据应该通过服务的 API(也就是服务间通信)来完成,但是有些特殊情景走 API 的话,会变得特别麻烦和低效,所以可以通过共享数据存储变通一下。

比如验证用户安全。用户会话建立和安全认证是由账号系统 Passport 统一负责的,但每个微服务也都有验证用户安全的需求,如果每次请求都要访问 Passport 一次十分麻烦和低效,我们的做法是所有微服务之间共享用户会话数据(放在 Redis 中),只有 Passport 有写入权限,其它微服务只有读权限。另外一种做法是使用 API 网关,所有验证都在网关完成,每个微服务都不用管用户验证,我们没有使用这种方法。

另外一个例子是某些使用频繁的公共数据库也使用共享存储。比如我们系统中食物数据使用特别频繁,我们直接把这部分的数据和模型以只读方式共享给其它微服务,这样使用食物数据就简单多了。

#30 楼 @jicheng1014 另外一点,我认为虽然 ServiceObject 中可以有多个实例方法,但是基于单一责任原则,服务主要动作建议只有一个,这是我们只使用一个 call 方法的原因。如果有多个主要动作还不如剥离成多个 ServiceObject,如果它们之间有关联逻辑要复用,可以通过类继承或模块 mix 达成,这也是用实例方法的好处之一。

#34 楼 @vincent 非常感谢 很详细。最近我也在把我项目的验证功能抽成微服务,可以参考你们的做法。

终于等来了

字幕听不到的部分是 瓦肯人

#39 楼 @novtopro 嗯 simple_comand 做的是一样的事情

@terry。的笑话视频啊

需要 登录 后方可回复, 如果你还没有账号请 注册新账号