Стать старшим среди миллионов программистов!

Введение

Это вторая статья из серии SOLID для жестко запрограммированной молодежи. В этой статье речь пойдет о Принципе Открытости/Закрытости — Принципе Открытия и Закрытия.

  1. Принцип единой ответственности
  2. Открытый/закрытый принцип
  3. Принцип подстановки Лисков.
  4. Принцип разделения интерфейсов
  5. Принцип инверсии зависимостей

Объясните принцип

Согласно этому принципу модуль должен удовлетворять следующим 2 условиям:

  • Простота расширения: при необходимости модуль можно легко обновить, расширить и добавить новые функции.
  • Сложно модифицировать: ограничение или запрет на изменение исходного кода существующего модуля.

На первый взгляд эти два условия кажутся слишком противоречивыми? Обычно, когда вы хотите добавить функциональность, вам нужно написать дополнительный код или отредактировать существующий код. Здесь принцип ограничивает изменение исходного кода !! Итак, как мы можем разработать модуль, который легко расширять, но трудно модифицировать?

Прежде чем мы поговорим о программировании, давайте проанализируем объект, хорошо спроектированный в соответствии с принципом Open-Off: пистолет. Чтобы стрелять дальше, мы можем прикрепить больше прицелов; Чтобы не издавать звука, можно приделать ствол глушителя; для увеличения количества патронов можно прикрепить дополнительные магазины; Когда нам нужен рукопашный бой, мы также можем прикрепить штыки.

Видно, что пистолет предназначен для легкого расширения функциональности без разборки и разборки его внутренних частей (исходный код). Подходящий модуль OCP также должен быть разработан таким же образом.

Пример

Давайте прочитаем код в примере ниже:

// We have 3 classes: square, circle, triangle, inherit the class Shape
public class Shape
{
}
public class Square: Shape
{
  public double Height {get; set; }
}
public class Circle: Shape
{
  public double Radius {get; set; }
}
public class Triangle: Shape
{
  public double FirstSide {get; set; }
  public double SecondSide {get; set; }
  public double ThirdSide {get; set; }
}

// Module print out the area of ​​the figure
public class AreaDisplay
{
  public double ShowArea (List <Shape> shapes)
  {
    foreach (var shape in shapes) {
      // If requested to change, add another shape, we have to modify the Area Calculator module
      if (shape is Square) {
        Square square = (Square) shape;
        var area + = Math.Sqrt (square.Height);
        Console.WriteLine (area);
      }
      if (shape is Triangle) {
        Triangle triangle = (Triangle) shape;
        double TotalHalf = (triangle.FirstSide + triangle.SecondSide + triangle.ThirdSide) / 2;
        var area + = Math.Sqrt (TotalHalf * (TotalHalf - triangle.FirstSide) *
        (TotalHalf - triangle.SecondSide) * (TotalHalf - triangle.ThirdSide));
        Console.WriteLine (area);
      }
      if (shape is Circle) {
        Circle circle = (Circle) shape;
        var area + = circle.Radius * circle.Radius * Math.PI;
        Console.WriteLine (area);
      }
    }
  }
}

У нас есть 3 класса: Square, Circle, Rectangle. Класс AreaDisplay вычисляет площадь этих фигур и печатает их. Согласно старому коду, для вычисления площади нам нужно использовать функцию if для проверки и принудительного ввода объекта, после чего начать вычисление. Легко увидеть, добавим ли мы в будущем больше классов, отредактируем класс AreaDisplay и напишем больше, если функция if. После редактирования мы должны скомпилировать и развернуть класс AreaDisplay, снова длинный и подверженный ошибкам, верно??

Применив OCP, мы улучшим следующее:

// We have 3 classes: square, circle, triangle, inherit the class Shape
// Convert logic to calculate the area into each class
public abstract class Shape
{
  public double Area ();
}
public class Square: Shape
{
  public double Height {get; set; }
  public double Area () {
    return Math.Sqrt (this.Height);
  }
}
public class Circle: Shape
{
  public double Radius {get; set; }
  public double Area () {
    return this.Radius * this.Radius * Math.PI;
  }
}
public class Triangle: Shape
{
  public double FirstSide {get; set; }
  public double SecondSide {get; set; }
  public double ThirdSide {get; set; }
  public double Area () {
    double TotalHalf = (this.FirstSide + this.SecondSide + this.ThirdSide) / 2;
    var area + = Math.Sqrt (TotalHalf * (TotalHalf - this.FirstSide) *
        (TotalHalf - this.SecondSide) * (TotalHalf - this.ThirdSide));
    return area;
  }
}

// Module print out the area of ​​the figure
public class AreaDisplay
{
  public double ShowArea (List <Shape> shapes)
  {
    foreach (var shape in shapes) {
      Console.WriteLine (shape.Area ());
    }
  }
}

Мы перемещаем область модуля в каждый класс. Класс AreaDisplay, просто распечатайте его. В будущем при добавлении нового класса нам нужно позволить этому классу наследовать исходный класс Shape. Класс AreaDisplay может печатать области дополнительных классов без необходимости модификации своего исходного кода.

Вывод

Принцип OCP появляется во всех уголках индустрии программирования. Одним из приложений этого принципа является система подключаемых модулей (для Eclipse, Visual Studio, надстройки Chrome). Чтобы добавить новые функции в программное обеспечение, вам необходимо установить эти плагины, не нужно вмешиваться в существующий исходный код.

Этот принцип также применяется при написании фреймворков/библиотек. Например, при использовании MVC мы не можем просматривать или изменять код существующих классов Router и Controller, но мы можем написать новые контроллеры, New Routers, чтобы добавить функциональность. Используя ionic-framework, мы можем загрузить дополнительный плагин, чтобы использовать функции захвата и сканирования штрих-кода, не касаясь исходного кода ionic.

Применяя этот принцип в дизайне, нам нужно определить, что нужно изменить, чтобы соответствовать этому изменению. Это очень сложная работа даже для опытных разработчиков. Это требует большого опыта, дальновидности и немного предвидения. Что делать, если я ошибочно догадываюсь, что нужно изменить? Просто сначала напишите код для запуска, а затем рефакторинг.

использованная литература





Принцип «открыто-закрыто в объектно-ориентированном проектировании
Принцип открыто-закрыто в объектно-ориентированном проектировании гласит: Принцип открыто-закрыто побуждает разработчиков программного обеспечения…www .eventhelix.com»