代码之家  ›  专栏  ›  技术社区  ›  Chris Baxter

闭包和类?

  •  4
  • Chris Baxter  · 技术社区  · 14 年前

    我有一个我想要能够处理的“规则”的概念。因此,我创建了下面的界面:

      public interface IRule<T>
      {
        Boolean IsSatisfiedBy(T value);
        String GetViolationMessage(T value);
      }
    

    我计划创建一系列“规则”类来表示系统当前支持的各种规则,例如:

      public class MatchesPatternRule : IRule<String>
      {
        private readonly Regex _regex;
        private readonly String _pattern;
    
        public MatchesPatternRule(String pattern)
        {
          Verify.IsFalse(String.IsNullOrWhiteSpace(pattern));
    
          _regex = new Regex(pattern);
          _pattern = pattern;
        }
    
        public Boolean IsSatisfiedBy(String value)
        {
          return _regex.IsMatch(value);
        }
    
        public String GetViolationMessage(String value)
        {
          return String.Format(RuleMessage.MatchesPatternViolation, _pattern, value);
        }
      }
    

    然后通过各种扩展方法使用这些规则,例如:

    public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern)
    {
      context.AddRule(new MatchesPatternRule(pattern));
      return context;
    }
    

    但是,我目前有20多个规则的计划,MatchesPatternRule类可以通过将扩展方法编写为:

    public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern)
      where T : IComparable
    {
      Verify.IsFalse(String.IsNullOrWhiteSpace(pattern));
    
      Regex regex = new Regex(pattern);
      context.AddRule(value => regex.IsMatch(value), value => String.Format(RuleMessage.MatchesPatternViolation, _pattern, value));
      return context;
    }
    

    好奇什么方法更好,为什么?两者都很容易被证明,最终达到最终结果。任何见解都将受到极大的赞赏!

    更新

    根据汤姆的反馈,我认为我选择了中间立场。我将创建一个静态类来保存每个“规则”的扩展方法。这将确保任何给定的规则都很容易找到,并将保持代码的有序性,同时也减少了代码的总量。

      public static class MatchesPatternRule
      {
        public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern)
        {
          return MatchesPattern<T>(context, pattern, pattern, RegexOptions.None);
        }
    
        public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern, String friendlyPattern)
        {
          return MatchesPattern<T>(context, pattern, friendlyPattern, RegexOptions.None);
        }
    
        public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern, RegexOptions options)
        {
          return MatchesPattern<T>(context, pattern, pattern, options);
        }
    
        public static ValidationContext<String> MatchesPattern(this ValidationContext<String> context, String pattern, String friendlyPattern, RegexOptions options)
        {
          Verify.IsFalse(String.IsNullOrWhiteSpace(pattern));
    
          Regex regex = new Regex(pattern);
          context.AddRule(value => regex.IsMatch(value), value => String.Format(RuleMessage.MatchesPatternViolation, _pattern, value));
    
          return context;
        }
      }
    
    2 回复  |  直到 14 年前
        1
  •  1
  •   Tom Morris    14 年前

    我不是C用户,但在Ruby和Scala中,有类似的选择。在类似于此上下文的情况下,拥有一个依附于特定接口的类似乎具有类似的闭包用途,尽管使用了更多的样板文件。当他们从技术上追求同一个目标时,问题肯定会变成哪一个最适合社会背景。

    那些本应该写这些规则的人是否足够聪明,能够让他们的头脑不受束缚?如果不是,基于类的解决方案可能是更好的解决方案。如果我戴上我的java-programmer-trying-to-understand-all-this-c faciness帽子,基于类的解决方案可能比学习所有这些奇怪的功能性东西要容易一些-我知道奇怪的功能性东西,但我可以想象我自己 知道了!只有你才能决定什么对那些将要写规则的人最好。如果你是唯一一个必须写规则的人,那就疯狂吧!从美学上选择你喜欢的。

    文档和元数据怎么样?未来的可扩展性?如果需要向规则中添加额外的字段怎么办?与基于闭包的解决方案相比,基于类的解决方案更容易记录吗?如果你必须找到并改变一个规则,哪一个会更容易做到?

        2
  •  1
  •   palto    14 年前

    你为什么不能两个都要?对于简单的规则,可以使用闭包。validationContext.addRule无法将闭包转换为规则。或者可能是一个将闭包转换为规则的扩展方法。