サブクラスの抽出 (リファクタリング-p330)
リファクタリング
Published: 2019-03-18

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「サブクラスの抽出」について書きます。

「サブクラスの抽出」 について

「サブクラスの抽出」を行う主なきっかけは、あるクラスが、特定のインスタンスだけでしか使われない振る舞いを持っていることがわかった場合です。

変更前

<?php

class JobItem
{
    private $_unitPrice;
    private $_quantity;
    private $_isLabor;
    private $_employee;


    public function __construct($unitPrice, $quantity, $isLabor, Employee $employee)
    {
        $this->_unitPrice = $unitPrice;
        $this->_quantity = $quantity;
        $this->_isLabor = $isLabor;
        $this->_employee = $employee;
    }

    public function getTotalPrice()
    {
        return $this->getUnitPrice() * $this->_quantity;
    }

    public function getUnitPrice()
    {
        return $this->_isLabor ?
            $this->_employee->getRate() :
            $this->_unitPrice;
    }

    public function getQuantity()
    {
        return $this->_quantity;
    }

    public function getEmployee()
    {
        return $this->_employee;
    }
}

class Employee
{
    private $_rate;

    public function __construct($rate)
    {
        $this->_rate = $rate;
    }

    public function getRate()
    {
        return $this->_rate;
    }
}

$e = new Employee(0.6);
$ji = new JobItem(2, 100, true, $e);
echo $ji->getTotalPrice() . "\n";

変更後

<?php

class JobItem2
{
    private $_unitPrice;
    private $_quantity;
    private $_isLabor;
    private $_employee;


    protected function __construct($unitPrice, $quantity, $isLabor, Employee2 $employee)
    {
        $this->_unitPrice = $unitPrice;
        $this->_quantity = $quantity;
        $this->_isLabor = $isLabor;
        $this->_employee = $employee;
    }

    public function getTotalPrice()
    {
        return $this->getUnitPrice() * $this->_quantity;
    }

    public function getUnitPrice()
    {
        return $this->_isLabor ?
            $this->_employee->getRate() :
            $this->_unitPrice;
    }

    public function getQuantity()
    {
        return $this->_quantity;
    }

    public function getEmployee()
    {
        return $this->_employee;
    }
}

class LaborItem2 extends JobItem2
{
    public function __construct($unitPrice, $quantity, $isLabor, Employee2 $employee)
    {
        parent::__construct($unitPrice, $quantity, $isLabor, $employee);
    }
}

class Employee2
{
    private $_rate;

    public function __construct($rate)
    {
        $this->_rate = $rate;
    }

    public function getRate()
    {
        return $this->_rate;
    }
}

$e = new Employee2(0.6);
$ji = new LaborItem2(2, 100, true, $e);
echo $ji->getTotalPrice() . "\n";