3

我构建了一个轻量级的 Ruby 代码来包装外部 API:

api = ExternalAPI.new
api.expensive_operation(object)

它工作正常。但是,由于 API 很昂贵,除非必要,我不想调用它。这就是为什么我要创建一个使用本地缓存包装 API 调用的更高级别的 API。我不希望应用程序不必担心有关如何缓存 API 的细节。(缓存可以通过内存、磁盘、算盘,甚至鸽子来完成——这不是应用程序关心的问题。)

这是我目前正在考虑的:

包装器 = ExternalAPIWrapper.new
wrapper.expensive_operation(object)

我不喜欢这个名字ExternalAPIWrapper。它是通用的,不传达包装器的目的。特别是,它并不表示它首先检查本地缓存,并且仅在必要时访问低级 API。

我正在寻找在这个起点上有所改进的答案。以下是我正在寻找的一些东西:

  1. 高级班更好的名字
  2. 更好的样式 API
  3. 可能有帮助的设计模式
  4. (也许是一个远景......)一个包装和缓存 API 调用的 Ruby gem
4

3 回答 3

3

对于#1,想到的名字是CachedExternalAPI:) 不过,不确定你所说的“更好的风格 API”是什么意思。

至于#3/4:我不知道 RubyGem 会做这种缓存的事情,但我会以“元编程”方式实现缓存的 API,自动生成缓存 API 调用的方法,例如

class CachedExternalAPI
  @cache = { }

  class << self

    [:foo, :bar, :baz].each do |m|
      define_method m do
        return (puts "Totally cached!"; @cache[m]) if not @cache[m].nil?
        puts "Not cached :("
        @cache[m] = 42
      end
    end

  end
end

CachedExternalAPI.foo()
CachedExternalAPI.foo()

CachedExternalAPI.bar()
CachedExternalAPI.bar()

哪个会产生

未缓存 :(
完全缓存!
未缓存 :(
完全缓存!

这当然假设所有 API 调用的缓存机制都是相同的。但是,如果您的 API 可以通过这种方式缓存,您可以保持缓存的 API 包装器相当干燥。

于 2012-07-18T19:38:48.467 回答
2

我的一个朋友 Rob 找到了 APICache

APICache(又名 api_cache)

APICache 允许使用强大的缓存层轻松包装任何 API 客户端库。它支持缓存(显然)、提供陈旧数据和限制 API 调用的数量。如果您只想缓存一个麻烦的 url,它也有一个方便的语法。

APICache 支持多种缓存策略,包括:

  • 一个简单的内存缓存
  • 通过Moneta的各种后端,“键值存储的统一接口”
  • Memcached via Dalli,以 Dalí 的记忆持久化命名
于 2012-07-18T22:05:52.963 回答
0

Too little detail to know exactly what you want but I thought of a bridge pattern straight away since you are essentially trying to decouple your abstraction and implementation when looking at varying your cache backend.

于 2012-07-18T20:00:49.610 回答