目的
「リファクタリング」を理解するためにサンプルコードを 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";