Open Closed Principle (OCP) — важный аспект S.O.L.I.D принципов объектно-ориентированного программирования. Он предполагает, что программные объекты (классы, модули, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации. Другими словами, разработчики должны иметь возможность добавлять новые функции в существующую кодовую базу, не изменяя ее текущую структуру.

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

Например, если пользователь пытается оплатить продукт в вашем веб-приложении, а ваши приложения имеют различные способы оплаты, такие как PayPal, кредитная/дебетовая карта, банковский перевод и т. д. Давайте рассмотрим код ниже.

// PaymentService.php
<?php

namespace App\Services;

class PaymentService
{
    public function pay($type, $amount)
    {
        switch ($type) {
            case 'paypal':
                // Do paypal payment logic
                break;
            case 'bank':
                // Do bank transfer payment logic
                break;
        }
    }
}

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

Вот пример с OCP.

// PaymentInterface.php
<?php

namespace App\Interfaces;

interface PaymentInterface
{
  public function pay($amount);
}

// PaypalPayment.php
<?php

namespace App\Payments;

use App\Interfaces\PaymentInterface;

class PaypalPayment implements PaymentInterface
{
  public function pay($amount)
  {
    // Paypal payment logic here
  }
}

// BankPayment.php
<?php

namespace App\Payments;

use App\Interfaces\PaymentInterface;

class BankPayment implements PaymentInterface
{
  public function pay($amount)
  {
    // Bank payment logic here
  }
}
// PaymentService.php
<?php

namespace App\Services;

class PaymentService
{
    public function pay(PaymentInterface $payment, $amount)
    {
        $payment->pay($amount);
    }
}

// in some classes that called PaymentService pay
<?php

namespace App\Classes;

class SomeClass
{
  public function pay()
  {
    // Use payment needed
    $payment = new Paypal();
    (new PaymentService())->pay($payment, 1000);
  }
}

В приведенном выше примере мы можем установить способ оплаты, как нам нужно, и если будут добавлены какие-либо другие способы оплаты, нам не нужно изменять или класс платежного сервиса. Нам осталось только создать новый платежный класс с реализацией PaymentInterface.

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

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