Рубрики
Без рубрики

S.O.L.I.D: Принцип Открытия/Закрытия

S.O.L.I.D Часть 2: Принцип Открытия/Закрытия. Помечено как ооп, java, шаблон проектирования, твердый.

Принцип S.O.L.I.D (Серия из 2 частей)

Согласно Вики :

В объектно-ориентированном компьютерном программировании SOLID – это мнемоническая аббревиатура пяти принципов проектирования, призванная сделать разработку программного обеспечения более понятной, гибкой и поддерживаемой.

SOLID – это аббревиатура для 5 важных принципов проектирования при выполнении ООП. Впервые он был представлен Робертом С. Мартином (/|Дядя Боб ) в его статье 2000 года Принципы проектирования и шаблоны проектирования .

ТВЕРДЫЙ означает –

  • S – Принцип Единой Ответственности
  • O – Принцип Открытия/Закрытия
  • L – Принцип подстановки Лискова
  • I – Принцип разделения интерфейсов
  • D – Принцип инверсии зависимостей

В этой статье я буду освещать O – Открытый/Закрытый принцип . Примечание – Примеры будут на Java, но применимы к любому языку ООП.

Принцип открытости/закрытости (OCP) – это ТВЕРДЫЙ принцип в котором говорится

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

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

Сначала мы рассмотрим пример, который нарушает принцип OCP.

// GeneralInvestment.java
public class GeneralInvestment {
  public Double initialAmount;
  public int year;
  public Double tax;

  public GeneralInvestment(Double initialAmount, int year, Double tax) {
    this.initialAmount = initialAmount;
    this.year = year;
    this.tax = tax;
  }
}

//InvestmentManager.java
public final class InvestmentManager {
  public Double calculateReturn(GeneralInvestment investment) {
    return investment.initialAmount + (investment.year * investment.initialAmount * investment.tax);
  }
}

Итак, у нас есть Общий инвестиционный класс и Инвестиционный менеджер класс. Единственная цель Инвестиционный менеджер предназначен для вычисления возвращаемого типа Общие инвестиции .

Идя дальше, у нас есть запрос функции для расчета рентабельности Передовые инвестиции . Давайте добавим немного кода для этого.

//AdvancedInvestment.java
public class AdvancedInvestment extends GeneralInvestment {
  public Double incremental;
  public int period;

  public AdvancedInvestment(Double initialAmount, int year, Double tax, Double incremental, int period) {
    super(initialAmount, year, tax);
    this.incremental = incremental;
    this.period = period;
  }
}

Теперь у нас есть Передовые инвестиции на месте. Давайте обновим наш Инвестиционный менеджер класс для ведения нового дела.

public final class InvestmentManager {
  public Double calculatereturn(GeneralInvestment investment) {
    if (investment instanceof AdvancedInvestment) {
      AdvancedInvestment advancedInvestment = (AdvancedInvestment) investment;
      return advancedInvestment.initialAmount
          + (advancedInvestment.year * advancedInvestment.initialAmount * advancedInvestment.tax)
          + (advancedInvestment.period * advancedInvestment.incremental * advancedInvestment.tax);
    } else {
      return investment.initialAmount + (investment.year * investment.initialAmount * investment.tax);
    }
  }
}

Это работает! Но это нарушает OCP, так как Инвестиционный менеджер класс является

  • Закрыт на продление
  • Открыт для внесения изменений

Давайте попробуем реализовать вышеупомянутый сценарий, не нарушая OCP.

Шаг 1: Создайте интерфейс

// Investment.java
interface Investment {
  public Double calculateReturn();
}

Шаг 2: Обновление Общие инвестиции и Расширенные инвестиции классы путем реализации Инвестиции интерфейс

//GeneralInvestment.java
public class GeneralInvestment implements Investment {
  public Double initialAmount;
  public int year;
  public Double tax;

  public GeneralInvestment(Double initialAmount, int year, Double tax) {
    this.initialAmount = initialAmount;
    this.year = year;
    this.tax = tax;
  }

  public Double calculateReturn() {
    return initialAmount + (year * initialAmount * tax);
  }
}

//AdvancedInvestment.java
public class AdvancedInvestment implements Investment {
  public Double incremental;
  public int period;
  public GeneralInvestment investment;

  public AdvancedInvestment(Double initialAmount, int year, Double tax, Double incremental, int period) {
    this.incremental = incremental;
    this.period = period;
    this.investment = new GeneralInvestment(initialAmount, year, tax);
  }

  public Double calculateReturn() {
    return investment.initialAmount + (investment.year * investment.initialAmount * investment.tax)
        + (period * incremental * investment.tax);
  }
}

Шаг 3: Окончательно обновите класс Инвестиционный менеджер

//InvestmentManager.java
public final class InvestmentManager {
  public Double calculateReturn(Investment investment) {
    return investment.calculateReturn();
  }
}

Вот диаграмма UML для уменьшения многословия:

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

Всегда имейте в виду, чтобы ваш код был открыт для расширения и закрыт для модификации. Это сделает обслуживание кода таким простым.

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

Мир! Если у вас есть какие-либо вопросы или отзывы, пожалуйста, не стесняйтесь комментировать ниже.

Принцип S.O.L.I.D (Серия из 2 частей)

Оригинал: “https://dev.to/linuxnerd/s-o-l-i-d-open-closed-principle-2lb0”