• Ruby Rack 及其应用 (上) at 2016年11月15日

    写得不错,👍

  • RubyConf China 2016 视频 at 2016年11月06日

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

  • RubyConf China 2016 视频 at 2016年10月31日

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

  • RubyConf China 2016 视频 at 2016年10月31日

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

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

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

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

  • RubyConf China 2016 视频 at 2016年10月30日

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

  • RubyConf China 2016 视频 at 2016年10月30日

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

  • 这种关联应该用什么? at 2016年10月09日

    Pad belongs_to :player Player has_many :pads

  • 为什么用 RPC at 2016年7月25日

    #26楼 @jayliud 今年打算在 RubyConf China 做一个 Rails 微服务化的主题演讲,敬请期待!

  • 为什么用 RPC at 2016年7月17日

    #23楼 @wangder 没有事务支持,分布式事务都比较复杂,如果真的需要,需要自己做接口支持,也就是说提供恢复操作接口,由自己控制。

  • 为什么用 RPC at 2016年7月17日

    #19楼 @jayliud 其实去年做过两次的 topic 分享,都是关于这个主题的,:)

Rubyist,写优雅的程序,做一个优雅的人。