我应该使用什么编程模式或策略来处理数据处理中的小不一致?

What programming patterns or strategy should I use to deal with small inconsistencies in data processing?

在我写的 ruby gem 中,我必须将某些已知查询参数作为输入并将它们按摩到查询字符串中,然后使用构造的 (url)字符串作为检索该数据的休息端点。

现在输入中出现了一些奇怪的不一致,我正在分叉我的代码以将输入规范化为一致的输出。

   def build_query(params, endpoint)
      limit      = Hash[limit:      params[:limit]   ||  0]
      skip       = Hash[skip:       params[:skip]    ||  0]
      asc        = Hash[asc:        params[:asc]     || ""]
      desc       = Hash[desc:       params[:desc]    || ""]

      query = [limit, skip, asc, desc].select { |hash| hash.values.none? { |val| val == '' || val == 0 } }
      encoded = query.map{ |q| q.to_query }.join("&")

      references = build_references(params[:include]) || ""

      query_string = references.empty? ? "#{endpoint}#{encoded}" : "#{endpoint}#{references}&#{encoded}"
    end

您将在上面看到 paramsreferences 部分与其余参数的处理方式不同。即将出现更多稍微不一致的边缘情况。我知道如何处理这些问题的唯一方法是在这个函数中继续分叉我的代码。很快就会变得凌乱!

那么我现在应该如何重构这段代码?我应该从哪里开始管理这种复杂性?我应该使用协作对象(ParamsBuilderQueryManager)和某种多态性策略吗?

我希望我的代码尽可能简单和实用。

plain = %i|limit skip asc desc| # plain values
built = { include: ->(input) { build_references(input) } } # procs

query = (plain | built).map do |p|
  case p
  when Symbol then params[p]
  when Array  then p.last.(params[p.first])
  end
end.reject(&:blank?).map(&:to_query).join("&")

[endpoint, query].join

基本上,您有两种类型的参数:那些您要按原样传递的参数(如 :limit,)和那些您要转换的参数(如 :include。)

前者只是通过,后者是使用此代码段开头指定的 lambda 列表转换的。

由于您在原始问题中使用了 to_query,我建议您使用 rails,因此您手头有 blank? 方法,无需显式检查是否为空字符串 and/or 个零。

在最后一步中,我们拒绝空格并用“&”号连接所有内容。