RubyConf RubyConf China 2016 视频

huacnlee for Ruby China · 发布于 2016年10月28日 · 最后由 chihwoo 回复于 2016年11月25日 · 5460 次阅读
De6df3
本帖已被设为精华帖!

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

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

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

共收到 39 条回复
De6df3 huacnlee 关闭了讨论 10月28日 10:31
De6df3 huacnlee 重新开启了讨论 10月28日 10:31
0967c2

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

De6df3 huacnlee RubyConf China 2016 会有录像吗? 中提及了此贴 10月28日 11:12
3211

前排支持👍

8楼 已删除
17767

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

20818

棒棒哒👍 。。。

1959

前排支持👍+1

E40b21

很棒了!声音有点稍小。

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

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

4898

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

1

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

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

下届务必用录屏方式。

10547

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

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

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

20394

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

162

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

162

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

244

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

1

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

332

#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.

10547

#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

D7469f

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

332

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

D7469f

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

332

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

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

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

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

332

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

D7469f

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

4416

终于等来了

8744

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

7643

多谢!

332

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

19671

nice啊

96

@terry。的笑话视频啊

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