Help us understand the problem. What is going on with this article?

Open-Closed Principle(開放閉鎖の原則)についてまとめた

More than 1 year has passed since last update.

はじめに

前回こちらの記事で、SOLID原則について調べつつまとめていきました。
https://qiita.com/kkkkkkkkkkk/items/ad5a7aeaee16bf55b3e2

今回は、SOLID原則のうちのひとつであるOpen-Closed Principle(開放閉鎖の原則)について考えていきたいと思います。

Open-Closed Principle(OCP)とは?

前回の記事でざっくり概要だけは触れましたが、改めて原則について確認していきます。

Open-Closed Principleとは、クラスは、拡張に対して開放され、修正に閉鎖されるべきであるという原則でした。

この原則を聞くだけだとイマイチ理解できないと思うので、さらに噛み砕いた表現をすると、簡単に拡張できて、修正が不要になるようにしよう!という原則です。

これでなんとなく原則意味の意味はつかめたと思います。

次は実際にコードを見ながら、原則の意味を確認していきます。

OCPに違反した例

まずはOCPに違反した例から見ていきたいと思います。

例としては、支払いを行うサービス(PaymentService)があり、そこで課金を行う仕組みがあるとします。

とりあえず、最初はカード支払いだけだったのでこんな感じで実装したとします。

その例がこちらです。

<?php
ini_set( 'display_errors', 1 );

class PaymentService {
    public function __construct(CardPayment $cardPayment){
        $this->cardPayment = $cardPayment;
    }

    public function pay()
    {
        $this->cardPayment->pay();
    }
}


class CardPayment {
    public function pay(){
        echo("<p>pay with card</p>");
    }
}


// カード支払い
$cardPayment = new CardPayment();
$payment = new PaymentService($cardPayment);
$payment->pay();

// 銀行支払い
// コード自体の修正が必要になる。

いかがでしょうか?

コード内のコメントにも記載していますが、現状のコードだと銀行支払いが必要になった場合の考慮がされておらず、コード自体の修正が必要になりますよね。

これは、OCPの修正に閉鎖されるべきであるに確かに違反していることがわかりますね。

OCPに遵守した例

今度はOCPに遵守した例を見ていきます。

こちらはさっそくコードを見てみましょう!

<?php
ini_set( 'display_errors', 1 );

class PaymentService {
    public function __construct(PaymentMethod $paymentMethod){
        $this->paymentMethod = $paymentMethod;
    }

    public function pay()
    {
        $this->paymentMethod->pay();
    }
}

interface PaymentMethod {
    public function pay();
}


class CardPayment implements PaymentMethod {
    public function pay(){
        echo("<p>pay with card</p>");
    }
}


class BankPayment implements PaymentMethod {
    public function pay(){
        echo("<p>pay with bank</p>");
    }
}


// カード支払い
$cardPayment = new CardPayment();
$payment = new PaymentService($cardPayment);
$payment->pay();

// 銀行支払い
$bankPayment = new BankPayment();
$payment = new PaymentService($bankPayment);
$payment->pay();

// アプリ支払い
// コレならコードを修正しなくてもアプリ支払いを追加できる

いかがでしょうか?

こちらはOCPに遵守していることがわかりますよね!

コード内のコメントにも記載していますが、これならアプリ支払いが増えてもコードの修正が不要になります。

まとめ

今回は、Open-Closed Principle(OCP)について学習しました。

業務の都合でしばらくQiitaの更新が途絶えてしまいましたが、SOLID原則の記事はやりきりたいと思います。

kkkkkou
フリーランスのPGです。 最近は、React、Next、Nuxtが多め。 サーバーサイドはLaravelかGo。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away