OCP-开闭原则

开闭原则

对扩展开放,对修改关闭

  public enum Color { Red,Green,Blue}
  public enum Size { Small, Medium, Large, Yuge }
  public class Product
  {
      public string Name;
      public Color Color;
      public Size Size;

      public Product(string name, Color color,Size size)
      {
          if(name==null)
          {
              throw new ArgumentNullException(paramName: nameof(name));
          }
          Name = name;
          Color = color;
          Size = size;
      }
  }

产品过滤器设置 违反开闭原则

    public class ProductFilter
  {
      public  IEnumerable<Product> FilterBySize(IEnumerable<Product> products,Size size)
      {
          foreach(var p in products)
          {
              if (p.Size == size)
                  yield return p;
          }
      }

      public  IEnumerable<Product> FilterByColor(IEnumerable<Product> products, Color color)
      {
          foreach (var p in products)
          {
              if (p.Color == color)
                  yield return p;
          }
      }


      public IEnumerable<Product> FilterBySizeAndColor(IEnumerable<Product> products, Size size,Color color)
      {
          foreach (var p in products)
          {
              if (p.Size == size && p.Color == color)
                  yield return p;
          }
      }
  }

重构后

  public interface ISpecification<T>
  {
      bool IsSatisfied(T t);
  }


  public interface IFilter<T>
  {
      IEnumerable<T> Filter(IEnumerable<T> items, ISpecification<T> spec);
  }

  public class ColorSpecification : ISpecification<Product>
  {
      private Color color;
      public ColorSpecification(Color color)
      {
          this.color = color;
      }
      public bool IsSatisfied(Product t)
      {
          return t.Color==color;
      }
  }
  public class SizeSpecification : ISpecification<Product>
  {
      private Size size;
      public SizeSpecification(Size size)
      {
          this.size = size;
      }
      public bool IsSatisfied(Product t)
      {
          return t.Size == size;
      }
  }

  public class AndSpecification<T> : ISpecification<T>
  {
      private ISpecification<T>  first,second;
      public AndSpecification(ISpecification<T> first, ISpecification<T> second)
      {
          this.first = first?? throw new ArgumentNullException(paramName: nameof(first));
          this.second = second ?? throw new ArgumentNullException(paramName: nameof(second));
      }
      public bool IsSatisfied(T t)
      {
          return first.IsSatisfied(t) && second.IsSatisfied(t);
      }
  }


  public class BetterFilter : IFilter<Product>
  {
      public IEnumerable<Product> Filter(IEnumerable<Product> items, ISpecification<Product> spec)
      {
          foreach(var i in items)
          {
              if (spec.IsSatisfied(i))
                  yield return i;
          }
      }
  }

测试示例

          var apple = new Product("Apple", Color.Green, Size.Small);
          var tree = new Product("Tree", Color.Green, Size.Large);
          var house = new Product("House", Color.Blue, Size.Large);

          Product[] products = { apple, tree, house };

          var pf = new ProductFilter();
          Console.WriteLine("Green products (old):");
          foreach(var p in pf.FilterByColor(products,Color.Green))
          {
              Console.WriteLine($" -  {p.Name} is green");
          }

          var bf = new BetterFilter();
          Console.WriteLine("Green products (new ):");
          foreach (var p in bf.Filter(products,new ColorSpecification( Color.Green)))
          {
              Console.WriteLine($" -  {p.Name} is green");
          }

          foreach (var p in bf.Filter(
              products, 
              new AndSpecification<Product>(
             new ColorSpecification(Color.Green),
             new SizeSpecification(Size.Large)
              )))
          {
              Console.WriteLine($" -  {p.Name} is big and blue");
          }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值