んだ日記

ndaDayoの技術日記です

【メモ】単一責任の原則

んだです。メモです。

SOLIDの原則を勉強してみたところ面白かったので、メモっていきます。

単一責任の原則って?

単一責任の原則=Single Responsibility Principle :SRP

「クラス・モジュールは、たった1つのアクターに対して責務を追うべき」という原則。

「会員管理システム」を例に

たとえば、会員管理システムを例にします。

この会員管理システムを使う人は

①管理者(Admin)

②一般ユーザー(User)

で、管理者と一般ユーザのそれぞれ権限は

①管理者(Admin)
  - 一般ユーザー情報にメールを送信できる

②一般ユーザー(User)
 - 一般ユーザー情報の名前・性別・趣味を閲覧できる

「1つのアクター」のアクターって??

アクターとは、ここでは

①管理者(Admin)

②一般ユーザー(User)

のこと。

「たった1つのアクターに対して責務を追うべき」とは、要するに

・管理者からの変更要求に対してのみ、変更するクラスになっているか?

または

・一般ユーザからの変更要求に対してのみ、変更するクラスになっているか?

具体的にコードでみていきましょう〜。

SRP違反なクラス

先ほどの会員管理システムをコードにしてみます。 SRP違反なコードです。

// Member.php
<?php

class Member
{
    private $name;
    private $sex;
    private $hobby;
    private $email;

    public function __construct($name, $sex, $hobby, $email)
    {
        $this->name = $name;
        $this->sex = $sex;
        $this->hobby = $hobby;
        $this->email = $email;
    }
    
    public function getProfile()
    {
        return [
            'name' => $this->name,
            'sex' => $this->sex,
            'hobby' => $this->hobby,
        ];
    }

    public function sendMail()
    {
        $to = $this->email;
        $subject = "お知らせ";
        $message = "こんにちわ" . $this->name .'さん';
        $headers = "From: from@test.jp";

        mail($to, $subject, $message, $headers);
    }
}

このMemberクラスが変更される場合は、どんな場合でしょうか?

1 「管理者」がメールの送信の処理を変更したい。

2 「一般ユーザ」が閲覧できる情報を変更したい

と、、2つのアクターに対して責務があることになってます。

ということで、SRPに違反している。

リファクタリングする

// Member.php
<?php

namespace App;

class Member
{
    public $name;
    public $sex;
    public $hobby;
    public $email;

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

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @return mixed
     */
    public function getSex()
    {
        return $this->sex;
    }

    /**
     * @return mixed
     */
    public function getHobby()
    {
        return $this->hobby;
    }

    /**
     * @return mixed
     */
    public function getEmail()
    {
        return $this->email;
    }
}
// Profile.php
<?php

namespace App;

class Profile
{
    private $member;

    public function __construct(Members $member)
    {
        $this->member = $member;
    }

    public function getProfile()
    {
        return [
            'name' => $this->member->getName(),
            'sex' => $this->member->getSex(),
            'hobby' => $this->member->getHobby(),
        ];
    }
}
// SendMail.php
<?php

namespace App;

class SendMail
{
    private $member;

    public function __construct(Members $member)
    {
        $this->member = $member;
    }

    public function sendMail()
    {
        $to = $this->member->getEmail();
        $subject = "お知らせ";
        $message = "こんにちわ" . $this->member->getName() .'さん';
        $headers = "From: from@test.jp";

        mail($to, $subject, $message, $headers);
    }
}

まとめ

「単一責任の原則=Single Responsibility Principle :SRP」

って、責務を必要最低限にとか、クラスの役割を1つだけとかだと思っておりましたが、厳密にはそーゆーことでもない。

・クラス・モジュールは、たった1つのアクターに対して責務を追うべき ・モジュールを変更する理由はたったひとつであるべきである

この定義が理解できやした。