【问题标题】:Feature flags best practice: condition inside or outside of a method? [closed]功能标志最佳实践:方法内部或外部的条件? [关闭]
【发布时间】:2013-05-08 14:27:18
【问题描述】:

我们使用功能标志来启用/禁用我们系统中的某些功能。

我与我的同事讨论了向代码本身添加功能标志的标准方法:

考虑以下方法:

def featured_method
  do_this
  do_that
end

我们的代码中大约有 15 个不同的地方调用了该方法。

您是否建议在每次调用此方法之前添加检查是否启用了该功能:

if feature_enabled?(:feature_key)
  featured_method
end

或者在 features_method 本身内部,像这样:

def featured_method
  if feature_enabled?(:feature_key)
    do_this
    do_that
  end
end

在方法本身中包含条件的好处是显而易见的:干掉代码,并且当您想要永久添加功能时,您只需从方法中删除条件。

在每次调用之前都有条件的好处是,在不进入featured_method代码本身的情况下,很清楚该方法是否被执行,这可以省去很多麻烦。

我想知道这些问题是否有其他解决方案或标准。

【问题讨论】:

  • 有些人会投票关闭anything
  • 大声笑,我不在乎,伙计,不用担心 :)

标签: ruby design-patterns feature-detection


【解决方案1】:

我很想将功能键控拆分到自己的模块中,并像这样使用它:

class Foo

  include FeatureKeyed

  def foo
    'foo'
  end
  feature_keyed :foo

  def bar
    'bar'
  end
  feature_keyed :bar

end

foo = Foo.new
p foo.foo    # => "foo"
p foo.bar    # => FeatureKeyed::FeatureDisabled

这是模块:

module FeatureKeyed

  class FeatureDisabled < StandardError ; end

  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods

    def feature_keyed(method_name, feature_key = method_name)
      orig_method = instance_method(method_name)
      define_method method_name do |*args|
        raise FeatureDisabled unless feature_enabled?(feature_key)
        orig_method.bind(self).call *args
      end
    end

  end

  def feature_enabled?(feature_key)
    feature_key == :foo
  end

end

注意事项:

  • feature_enabled?硬编码启用的功能名称。你会改变的。
  • 如果禁用某个功能,此代码会引发异常。您问题中的代码只是返回。做对你的应用有意义的事情。如果您需要为不同的方法提供不同的“未启用”行为,则可以将该行为传递给 feature_keyed。
  • 方法 _feature_keyed_ 将采用第二个参数,即功能键。如果缺少,则使用方法的名称作为功能键。

【讨论】:

  • 非常非常优雅,我喜欢它。
【解决方案2】:

我会合并这两种方法。

这将导致调用方出现 DRY 代码。它不会违反feature_method 中的 SRP,它会清楚地传达正在发生的事情 - 如果你能找到比我更好的名字:

def may_execute_featured_method
  featured_method if feature_enabled?(:feature_key)
end

def featured_method
  do_this
  do_that
end

调用者会使用may_execute_featured_method

【讨论】:

  • 鼓励投反对票的人解释投反对票。否则我无法改进答案。
  • 这实际上是一个不错的方法:)
猜你喜欢
  • 2014-11-18
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 2014-02-16
相关资源
最近更新 更多