スーパークラスの抽出 (リファクタリング-p336)
リファクタリング
Published: 2019-03-18

目的

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

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

「スーパークラスの抽出」 について

似通った特性を持つ2つのクラスがある。

コードの重複は、システムにおける主要な問題点の1つです。

変更前

<?php

class Employee
{
    private $_name;
    private $_annualCost;
    private $_id;

    public function __construct($name, $id, $annualCost)
    {
        $this->_name = $name;
        $this->_id = $id;
        $this->_annualCost = $annualCost;
    }

    public function getId()
    {
        return $this->_id;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function getAnnualCost()
    {
        return $this->_annualCost;
    }
}

class Department
{
    private $_name;
    private $_staff = [];

    public function __construct($name)
    {
        $this->_name = $name;
    }

    public function getTotalAnnualCost()
    {
        $e = $this->getStaff();
        $result = 0;
        foreach ($e as $v) {
            $result += $v->getAnnualCost();
        }

        return $result;
    }

    public function getHeadCount()
    {
        return count($this->_staff);
    }

    public function addStaff(Employee $arg)
    {
        $this->_staff[] = $arg;
    }

    public function getStaff()
    {
        return $this->_staff;
    }

    public function getName()
    {
        return $this->_name;
    }
}

$e1 = new Employee('emp1', 100, 2000);
$e2 = new Employee('emp2', 200, 5000);

echo $e1->getName() . "\n";
echo $e2->getName() . "\n";

$d = new Department('department1');
$d->addStaff($e1);
$d->addStaff($e2);

echo $d->getName() . "\n";
echo $d->getTotalAnnualCost() . "\n";

変更後

<?php

abstract class Party
{
    private $_name;

    protected function __construct($name)
    {
        $this->_name = $name;
    }

    public function getName()
    {
        return $this->_name;
    }

    abstract public function getAnnualCost();
}

class Employee2 extends Party
{
    private $_annualCost;
    private $_id;

    public function __construct($name, $id, $annualCost)
    {
        parent::__construct($name);
        $this->_id = $id;
        $this->_annualCost = $annualCost;
    }

    public function getId()
    {
        return $this->_id;
    }

    public function getAnnualCost()
    {
        return $this->_annualCost;
    }
}

class Department2 extends Party
{
    private $_staff = [];

    public function __construct($name)
    {
        parent::__construct($name);
    }

    public function getAnnualCost()
    {
        $e = $this->getStaff();
        $result = 0;
        foreach ($e as $v) {
            $result += $v->getAnnualCost();
        }

        return $result;
    }

    public function getHeadCount()
    {
        return count($this->_staff);
    }

    public function addStaff(Employee2 $arg)
    {
        $this->_staff[] = $arg;
    }

    public function getStaff()
    {
        return $this->_staff;
    }
}

$e1 = new Employee2('emp1', 100, 2000);
$e2 = new Employee2('emp2', 200, 5000);

echo $e1->getName() . "\n";
echo $e2->getName() . "\n";

$d = new Department2('department1');
$d->addStaff($e1);
$d->addStaff($e2);

echo $d->getName() . "\n";
echo $d->getAnnualCost() . "\n";