Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1336. #ЗаметкиНаПолях #DesignPrinciples OCP Против YAGNI. Начало В этой серии постов рассмотрим противоречия между принципом Open/Closed и принципом «Вам это не понадобится». OCP Принцип Open/Closed гласит, что: «Программные сущности (классы, модули, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации.» В настоящее время существует две интерпретации этого определения: 1. Дядюшка Боб Мартин говорит о предотвращении волновых эффектов. Когда вы изменяете часть кода, вам не нужно вносить изменения во всю базу кода, чтобы приспособиться к этой модификации. В идеале вы должны иметь возможность добавлять новые функции, ничего не меняя в существующем коде. Обычно это реализуется с помощью полиморфизма. Например, следующий пример нарушает версию OCP Мартина:
public void Draw(Shape shape)
{
  switch (shape.Type)
  {
    case ShapeType.Circle:
      DrawCircle(shape);
      break;
    case ShapeType.Square:
      DrawSquare(shape);
      break;
    default:
      throw new 
       ArgumentOutOfRangeException();
  }
}

Здесь, чтобы ввести новую форму, вам нужно будет изменить метод Draw. Чтобы исправить это, вы можете создать абстрактный класс Shape, а затем перенести логику рисования в подклассы:
public abstract class Shape
{
  public abstract void Draw();
}
 
public class Circle : Shape
{
  public override void Draw()
  { … }
}

Теперь, если нужно добавить новую фигуру, вы просто создаете подкласс и переопределяете метод Draw. Так вы закрыли класс Shape и открыли точку расширения в нём. 2. Бертран Мейер же говорит об обратной совместимости. Когда есть несколько взаимозависимых модулей, вы не можете просто изменить свой модуль, когда хотите, вам нужно учитывать его клиентов. Например, для библиотеки с открытым методом
CreateCustomer(string email)
вы не можете просто добавить новый обязательный параметр:
CreateCustomer(string email, string accountNumber)

Это будет критическим изменением для клиентского кода, который уже привязан к исходной версии метода. Это можно делать во время разработки, но не после публикации. Если нужно внести изменение после публикации, вы создаёте новый модуль (версию модуля). Однако вы по-прежнему можете изменять реализацию, если она не меняет API. Вся тема управления версиями веб-API — это, по сути, принцип OCP Мейера. Ещё один важный момент: версия OCP Мейера имеет смысл только в контексте нескольких команд разработчиков, когда каждый модуль разрабатывается разными командами. Если вы являетесь и автором, и «клиентом» кода, нет необходимости придерживаться таких сложных схем. Итак, две разновидности OCP, несмотря на то что имеют одно и то же имя, различаются по основному назначению. Код со switch, приведённый ранее, нарушает интерпретацию OCP Мартина, но не противоречит интерпретации Мейера. Интерпретация Мартина шире. Она направлена на сокращение количества изменений в целом, возможность расширить поведение ПО с небольшим изменением исходного кода или без него. Интерпретация Мейера направлена только на сокращение критических изменений: изменений, которые могут вызвать проблемы при совместной работе нескольких команд. Продолжение следует… Источник: https://enterprisecraftsmanship.com/posts/ocp-vs-yagni/