xunlei 发表于 2015-11-8 12:51:54

OCP开放-封闭原则

  软件实体(类,模块,函数等)应该是可扩展的,但是不可修改
优点:通过扩展已有软件系统,可以提供新的行为,以满足对软件的新的需求,使变化中的软件有一定的适应性和灵活性。已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。
下边举一个从不符合ocp到符合ocp的例子,shap示例在很多书中提到,我们这里用它来阐明ocp。不符合ocp的代码如下:
class Circle
    ...{
      private double Radius;

      public double radius
      ...{
            get ...{ return Radius; }
            set ...{ Radius = value; }
      }
      private double x;

      public double X
      ...{
            get ...{ return x; }
            set ...{ x = value; }
      }
      private double y;

      public double Y
      ...{
            get ...{ return y; }
            set ...{ y = value; }
      }
      public void Draw()
      ...{
            Console.WriteLine("画圆");
      }
    }
class Square
    ...{
      private double x;

      public double X
      ...{
            get ...{ return x; }
            set ...{ x = value; }
      }
      private double y;

      public double Y
      ...{
            get ...{ return y; }
            set ...{ y = value; }
      }

      private double lenth;

      public double Lenth
      ...{
            get ...{ return lenth; }
            set ...{ lenth = value; }
      }
      private double width;

      public double Width
      ...{
            get ...{ return width; }
            set ...{ width = value; }
      }
      public void Draw()
      ...{
            Console.WriteLine("画正方形");
      }

    }
static void Main(string[] args)
      ...{
            List<object> list = new List<object>();
            list.Add(new Circle());
            list.Add(new Square());
            DrawAll(list);
      }
      static void DrawAll(List<object> list)
      ...{
            foreach (object var in list)
            ...{
                if (var is Circle)
                ...{
                  ((Circle)var).Draw();
                }
                else
                ...{
                  ((Square)var).Draw();
                }
            }
      }  以上代码的问题是当增加新的图形时DrawAll函数要做比较大的修改工作,这很容易影响原本可以正常工作的部分,因为增加图形的变化可能性非常大,而且实际上当从画一种图形到画两种图形时我们已经发现了问题,我们不能再错过改成错误的机会,我们要对以上源代码进行大规模的重构。
interface IShap
    ...{
      void Draw();
    }
class Circle : IShap
    ...{
      private double Radius;

      public double radius
      ...{
            get ...{ return Radius; }
            set ...{ Radius = value; }
      }
      private double x;

      public double X
      ...{
            get ...{ return x; }
            set ...{ x = value; }
      }
      private double y;

      public double Y
      ...{
            get ...{ return y; }
            set ...{ y = value; }
      }
      public void Draw()
      ...{
            Console.WriteLine(&quot;画圆&quot;);
      }

    }
class Square : IShap
    ...{
      private double x;

      public double X
      ...{
            get ...{ return x; }
            set ...{ x = value; }
      }
      private double y;

      public double Y
      ...{
            get ...{ return y; }
            set ...{ y = value; }
      }

      private double lenth;

      public double Lenth
      ...{
            get ...{ return lenth; }
            set ...{ lenth = value; }
      }
      private double width;

      public double Width
      ...{
            get ...{ return width; }
            set ...{ width = value; }
      }
      public void Draw()
      ...{
            Console.WriteLine(&quot;画正方形&quot;);
      }

    }
static void Main(string[] args)
      ...{
            List<IShap> list = new List<IShap>();
            list.Add(new Circle());
            list.Add(new Square());
            DrawAllShap(list);
      }
      static void DrawAllShap(List<IShap> list)
      ...{
            foreach (IShap shap in list)
            ...{
                shap.Draw();
            }
      }  以上代码在增加新的图形的时候只需实现Ishap接口,根本就不需要修改DrawAllShap函数,这样DrawAllShap函数就符合了ocp。
  当画图时需要按某种顺序时,这种设计就没办法符合ocp原则了,如下更改是在需要顺序支持德尔符合ocp设计的代码(表格法)
class CompareShap:IComparer<IShap>
    ...{
      Dictionary<Type, int> table = new Dictionary<Type, int>();
      public CompareShap()
      ...{
            table.Add(typeof(Circle), 1);
            table.Add(typeof(Square), 2);
      }

      private int PriorityFor(Type type)
      ...{
            if (table.ContainsKey(type))
            ...{
                return table;
            }
            else
            ...{
                return 0;
            }
      }

      IComparer 成员#region IComparer<IShap> 成员

      public int Compare(IShap x, IShap y)
      ...{

            int p1 = PriorityFor(x.GetType());
            int p2 = PriorityFor(y.GetType());
            return p1.CompareTo(p2);
      }

      
      #endregion
    }  调用程序:
class Program
    ...{
      static void Main(string[] args)
      ...{
            List<IShap> list = new List<IShap>();
            list.Add(new Circle());
            list.Add(new Square());
            DrawAllShap(list);
      }
      static void DrawAllShap(List<IShap> list)
      ...{
            list.Sort(new CompareShap());
            foreach (IShap shap in list)
            ...{
                shap.Draw();
            }
      }
    }             版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: OCP开放-封闭原则