这个 repository 模式 Ruby 实现看上去还不错

DDD · chenge · 于 发布 · 最后由 lvjian700回复 · 585 次阅读
46

领域驱动设计中,也就是Domain Driven Development, 简称DDD的一种设计方法,Repository是一个重要的支撑模式。

这个代码演示了内存方式,很简单,是用hash来模拟的。


class InMemoryBackend
  def initialize
    @counter = 0
    @map = {}
  end

  def create(record)
    @counter = @counter + 1
    record.id ||= @counter
    map_for(record)[record.id] = record
  end

  def update(record)
    map_for(record)[record.id] = record
  end

  def delete(record)
    map_for(record).delete record.id
  end

  def find(klass, id)
    map_for_class(klass).fetch id
  end

  def all(klass)
    map_for_class(klass).values
  end

  def query(klass, selector)
    send "query_#{selector.class.name.underscore}", selector
  end

  private
  def map_for_class(klass)
    @map[klass.to_s.to_sym] ||= {}
  end

  def map_for(record)
    map_for_class(record.class)
  end
end

接下来,可以用User来实验

class User
  attr_accessor :id, :name 
end

db = InMemoryBackend.new
user = User.new
user.id = 1
user.name = 'Bill'
db.create(user)
db.find(User, 1)

文章中有比较完整的介绍,英文链接

作者Hawkins写了很多不错的博客,值得一读。


「软件匠艺社区」旨在传播匠艺精神,通过分享好的「工作方式」和「习惯」以帮助程序员更加快乐高效地编程。
共收到 2 条回复
1
hkliya · #1 ·

谢谢分享!

30
lvjian700 · #2 ·

InMemoryBackend 可以当成 Repository 的 Adapter

Repository Pattern 推荐采用 ModelNameRepository 的命名方式。

比如 TopicRepository, InMemoryAdapter, S3Adapter

class TopicRepository
  def initialize(adapter = InMemoryAdapter.new)
    @adapter = adapter
  end
end
in_memory_repo = TopicRepository.new
s3_repo = TopicRepository.new(S3Adapter.new)

如果不需要同时支持多个存储方式,可以 hardcode adapter

class TopicRepository
  include HTTParty
  base_url 'example.com'

  class << self
    def create(options)
    end
  end
end
TopicRepository.create(options)
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。