んだ日記

ndaDayoの技術日記です

PHPで『リファクタリング―プログラムの体質改善テクニック』を実装してみる (5) メソッドの移動

第二回の記事

nda-desu.hatenablog.com

こちらの記事で、映画の分類のswitch文をRentalクラスに移動しました。

んが、

Rentalクラスへのswitch文のメソッドの移動は、良くない例でした。。

なぜなら、

他のオブジェクトの属性を調べるためswitchを書くことは、常に間違いです。 switch文は、他のオブジェクトではなく自分自身について行うべきなのです。 p,34

映画のカテゴリのデータを保持しているのはMovieクラスなので、映画のカテゴリによるswitch文を置くとすれば、Movieクラスの方がいいからです。

ということで、Movieクラスに移動させていきます。

リファクタリング前のコード

Rental.php

<?php

namespace App;

use App\Movie;

class Rental
{
    
    ~省略~ 
    /**
     * ビデオのカテゴリとレンタル泊数に応じてポイントを返す
     *
     * @return float|int
     */
    public function getCharge()
    {
        $result = 0;
        switch ($this->getMovie()->getPriceCode()) {
            case Movie::REGULAR:
                $result += 2;
                if ($this->getDaysRented() > 2) {
                    $result += ($this->getDaysRented() - 2) * 1.5;
                }
                break;
            case Movie::NEW_RELEASE:
                $result += $this->getDaysRented() * 3;
                break;
            case Movie::CHILD:
                $result += 1.5;
                if ($this->getDaysRented() > 3) {
                    $result += ($this->getDaysRented() - 3) * 1.5;
                }
                break;
        }
        return $result;
    }
}

switch文をMovieクラスに移動する

Movie.php

<?php

namespace App;

use App\Rental;

class Movie
{
    
    ~省略~ 
    /**
     * ビデオのカテゴリとレンタル泊数に応じてポイントを返す
     *
     * @param $dayRented
     * @return float|int
     */
    public function getCharge($dayRented)
    {
        $result = 0;
        switch ($this->getPriceCode()) {
            case Movie::REGULAR:
                $result += 2;
                if ($dayRented > 2) {
                    $result += ($dayRented - 2) * 1.5;
                }
                break;
            case Movie::NEW_RELEASE:
                $result += $dayRented * 3;
                break;
            case Movie::CHILD:
                $result += 1.5;
                if ($dayRented > 3) {
                    $result += ($dayRented - 3) * 1.5;
                }
                break;
        }
        return $result;
    }
}

Rental.php

<?php

namespace App;

use App\Movie;

class Rental
{
    
    ~省略~ 
    /**
     * ビデオのカテゴリとレンタル泊数に応じてポイントを返す
     *
     * @return float|int
     */
    public function getCharge()
    {
        return $this->movie->getCharge($this->dayRented);
    }
}