Принципы в C# - часть 3. Принцип открытости-закрытости

  • Михаил
  • 12 мин. на прочтение
  • 91
  • 19 Dec 2018
  • 19 Dec 2018

Принцип Open-Closed (или OCP для краткости) гласит:

Объекты или сущности должны быть открыты для расширения, но закрыты для модификации.

«Открыто для расширений» означает, что нам нужно разработать наш код, чтобы добавить функциональные возможности при создании новых требований, а «Закрыто для изменений» означает, что мы уже разработали наш код, который прошел тестирование и проверки, его можно только изменить. в случае обнаружения ошибки.
 

public class Rectangle
{
    public double Height { get; set; }
    public double Width { get; set; }
}

 

public class AreaCalculator
{
    public double TotalArea(Rectangle[] rectangles)
    {
        double result = 0;
        foreach(Rectangle rectangle in rectangles
            result += rectangle.Height * rectangle.Width;

        return result;
    }
}

 

Но наше приложение получило новое требование для вычисления площади круга.
 

public class Circle
{
    public double Radius { get; set; }
}

 

Чтобы это работало, нам также нужно изменить AreaCalculatorкласс.
 

public class AreaCalculator
{
  public double TotalArea(object[] shapes)
  {
      double result = 0;

      foreach(object shape in shapes)
      {
          if(shape is Rectangle)
          {
              Rectangle rectangle = (Rectangle)obj;
              result += rectangle.Height * rectangle.Width;
          }
          if(shape is Circle)
          {
              Circle circle = (Circle)obj;
              result += circle.Radius * circle.Radius * Math.PI;
          }
      }
    return result;
  }
}

 

С этими изменениями мы добавили Circleв наше приложение.
Но что, если нам нужно добавить a Triangleили a Square? Нам нужно будет добавлять все больше и больше ifоператоров в наш TotalAreaметод.
Здесь нам на помощь приходит Принцип Открытого-Закрытого.
В этом примере Rectangleи Circleможет быть получено из одного и того же абстрактного понятия, файл Shape.
 

public abstract class Shape
{
    public double CalculateArea();
}

 

Теперь давайте воспользуемся Shapeклассом в наших «Фигурах».
 

public class Rectangle: Shape
{
    public double Height { get; set; }
    public double Width { get; set; }

    public double CalculateArea()
    {
        return Height * Width;
    }
}

public class Circle: Shape
{
    public double Radius { get; set; }

    public double CalculateArea()
    {
        return Radius * Radius * Math.PI;
    }
}

 

С нашими фигурами, реализующими CalculateAreaиз нашего Shapeкласса, нам нужно обновить AreaCalculatorкласс.
 

public class AreaCalculator
{
  public double TotalArea(Shape[] shapes)
  {
      double result = 0;

      foreach(Shape shape in shapes)
      {
          result += shape.CalculateArea();
      }

    return result;
  }
}

 

С этими изменениями теперь мы реализуем принцип Open-Closed. Наше приложение открыто для расширений (например, создание Triangleкласса), но закрыто для модификаций, модифицируя только в случае обнаружения каких-либо ошибок.