Ruby中的存储库或网关模式

ser*_*nfo 8 ruby architecture design-patterns ruby-on-rails

如何在Ruby中实现Repository或Gateway模式?

我来自一个C#世界,我通常抽象出我的数据访问,但是使用ActiveRecord作为Ruby中的默认数据访问机制,如何实现这一点并不明显.

我通常会做在C#是抽象的接口工作,然后有具体的实现EFCustomerRepository,NHibernateCustomerRepository而且InMemoryCustomerRepository并根据我注入相匹配的具体落实情况.

那么现在,Ruby的方式是什么?!

据我所知,在动态语言中你不需要像DI(依赖注入)这样的东西.Ruby具有强大的语言功能,可以实现mixins之类的功能.

但是你会定义mixin在类或模块级静态使用吗?

如果我想针对内存存储库开发并在生产中我将切换到我的ActiveRecord-Repository,如何编写我的业务逻辑?

如果我可能在错误的道路上,因为我习惯于用静态类型语言思考.如何以Ruby的方式处理这项任务?基本上我想让我的持久层抽象,它的实现可以互换.

编辑:我指的是罗伯特c.martins(unclebob)关于建筑的基调

谢谢你的帮助...

Mla*_*vić 2

嗯,ActiveRecord 已经提供了抽象持久层 - 它有几个不同的适配器,允许它使用不同的数据库后端。此外,它是开源的,因此您可以自由地查看它是如何实现的。

乍一看,您可以看到它还有一个所有其他适配器都继承的AbstractAdapter,但是,由于 Ruby 是动态的鸭子类型语言,AbstractAdapter不必包含将在子类中重写的抽象方法,也没有定义他们应该遵守的“契约”。

编辑:

下面是一个关于如何在 Ruby 中抽象存储的简单草图,但不确定它到底是什么模式:

# say you have an AR model of a person
class Person < ActiveRecord::Base
end

# and in-memory store of persons (simply, a hash)
IN_MEMORY_STORE = {
  :Person => ['Tim', 'Tom', 'Tumb']
}

# this will abstract access
class MyAbstractModel
  def initialize item, adapter
    @item = item
    @adapter = adapter
  end

  # get all elements from the store
  def all
    case @adapter
    when :active_record
      # pull from database:
      Object.const_get(@item).all
    when :in_memory_store
      # get from in-memory store
      IN_MEMORY_STORE[@item]
    else
      raise "Unknown adapter"
    end
  end
end

# get all Persons from in-memory storage...
p MyAbstractModel.new(:Person, :in_memory_store).all
# ...and from a database
p MyAbstractModel.new(:Person, :active_record).all
Run Code Online (Sandbox Code Playgroud)