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

Single Responsibility Principle(単一責務の原則)について考えた

More than 1 year has passed since last update.

はじめに

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

今回は、SOLID原則のうちのひとつであるSingle Responsibility Principle(単一責務の原則)について考えていきたいと思います。

Single Responsibility Principleの復習

Single Responsibility Principleとは、日本語で単一責務の原則で、クラスを変更する理由は1つでなければならないという意味でした。

そもそもクラスを変更する理由が1つではない場合ってどんなものなのか気になりましたので考えてみました。

ダメな例

クラスを変更する理由が1つではない場合について調べていくと、God objectという単語に行き着きました。

God objectとは?

In object-oriented programming, a God object is an object that knows too much or does too much. The God object is an example of an anti-pattern.
引用: https://en.wikipedia.org/wiki/God_objectK

God objectとは、アンチパターンのひとつで、大量のメソッドなどを保有して非常に多く事をやりすぎてしまう万能なオブジェクト(クラス)ということですね。

God(神)のオブジェクトって別にいい意味ではなく、むしろ悪い意味なんですね。

次に示すのがこのGod objectの例で、単一責務の原則に違反していると考えられます。

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

class Person {
    private $name;
    private $email;

    public function __construct(string $name, string $email){
        $this->name = $name;

        if($this->validateEmail($email)) {
            $this->email = $email;
        }
        else {
            throw new Exception('Invalid Email');
        }
    }

    private function validateEmail(string $email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

    public function greet() {
        echo("Hello");
    }
}


$person = new Person("test", "test@test.com");
$person->greet();

別に大量のメソッドを保有しているわけではありませんが、PersonクラスでEmailに関する処理も行っていて、Personクラスで多く事をやりすぎてしまっています。

良い例(さらに改善の余地はあるかと思いますが、、、)

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

class Person {
    private $name;
    private $email;

    public function __construct(string $name, Email $email){
        $this->name = $name;
        $this->email = $email;
    }

    public function greet() {
        echo("Hello");
    }
}

class Email {
    private $email;

    public function __construct(string $email){
        if($this->validateEmail($email)) {
          $this->email = $email;
        }
        else {
            throw new Exception('Invalid Email');
        }        
    }

    private function validateEmail(string $email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
}

$email = new Email("test@test.com");
$person = new Person("test", $email);
$person->greet();

これでPersonクラスでは、Personに関する処理、Emailクラスでは、Emailに関する処理になりました。
ざっくりですが、単一責務にはなりました。

もっと色々リファクタリングの余地はあるのかとは思いますが、単一責務の原則を説明する上では、割と上記のような単純なサンプルがわかりやすいですね。

最後に

今回は、Single Responsibility Principle(単一責務の原則)についてまとめました。

業務の関係で執筆時間がなくなってしまいましたが、なんとか短時間で書き終わって良かったです。

OOP(オブジェクト指向)は苦手分野なので、地道にがんばります。

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