オブ脳の演習(4)。ボーナスを答えるメソッドを追加する。

オブ脳 in PHP

step4 ボーナスはいくら?

ProEvo > PHP Evo > オブ脳 in PHP > step4 ボーナスはいくら?


1. 仕様から方針を決める
1.1 変更点
2. テストの変更
2.1 テストケースのリファクタリング
3. 属性"基本給"の追加
3.1 社員クラスの変更
3.2 給料計算の変更
3.3 社長クラスの変更
4. ボーナス計算メソッドの追加
4.1 社員クラスの変更
4.2 社長クラスの変更
5. 実行

1. 仕様から方針を決める

1.1 変更点

演習の仕様を元に機能の追加・変更を決定します。
変更は以下のようになります。
  1. 社員クラスに属性"基本給"を設定 (ボーナスと給料の計算の両方に使用するため)
  2. 基本給を設定するメソッドを追加
  3. 給料計算メソッドを引数ではなく属性から計算するように変更
  4. ボーナスを計算するメソッドを追加

2. テストの変更

2.1 テストケースのリファクタリング

まずはテストケースのリファクタリングをします。
変更点は親クラスの社員クラスを変更します。これのテストに対応するため、担当・主任・部長・取締役の各テストを社員テストの子クラスにします。

ソースは次のようになります。

Tests/shainTest.php
<?php
require_once 'PHPUnit.php';

class shainTest extends PHPUnit_TestCase {
	var $shain;

}
?>
		
Tests/tantouTest.php
<?php
require_once 'shainTest.php';
require_once 'tantou.php';

class tantouTest extends shainTest {
	function tantouTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Tantou();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("担当が普通に立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$kyuryou = $this->shain->getKyuryou(100);
		$this->assertEquals(100, $kyuryou);
	}
}
?>
		
Tests/shuninTest.php
<?php
require_once 'shainTest.php';
require_once 'shunin.php';

class shuninTest extends shainTest {
	function shuninTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Shunin();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("主任がすばやく立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$kyuryou = $this->shain->getKyuryou(100);
		$this->assertEquals(201, $kyuryou);
	}
}
?>
		
Tests/buchouTest.php
<?php
require_once 'shainTest.php';
require_once 'buchou.php';

class buchouTest extends shainTest {
	function buchouTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Buchou();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("部長がだるそうに立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$kyuryou = $this->shain->getKyuryou(100);
		$this->assertEquals(300, $kyuryou);
	}
}
?>
		
Tests/torishimariyakuTest.php
<?php
require_once 'shainTest.php';
require_once 'torishimariyaku.php';

class torishimariyakuTest extends PHPUnit_TestCase {
	function torishimariyakuTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Torishimariyaku();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("取締役がふんぞりかえって立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$kyuryou = $this->shain->getKyuryou(100);
		$this->assertEquals(402, $kyuryou);
	}
}
?>
		
この時点でテストを実行します。すべてグリーンなら修正は完了です。
[テスト実行結果]

3. 属性"基本給"の追加

3.1 社員クラスの変更

基本給は各社員に共通なので社員クラスに追加します。
あわせて、setter/getterメソッドも実装します。
ソースは次のようになります。

shain.php
<?php
/*
 * 社員用共通クラス
 */
class Shain {
	var $kihonkyu;

	function setKihonkyu($kihonkyu)
	{
		$this->kihonkyu = $kihonkyu;
	}

	function getKihonkyu($kihonkyu)
	{
		return $this->kihonkyu;
	}

	function standup()
	{
	}

	function getKyuryou()
	{
	}
}
?>
		

3.2 給料計算の変更

仕様の変更に伴い、給料計算メソッドから引数がなくなりました。
これにあわせてテストもsetterで基本給を設定する形に変更します。
各ソースは次のようになります。

Tests/tantouTest.php
<?php
require_once 'shainTest.php';
require_once 'tantou.php';

class tantouTest extends shainTest {
	function tantouTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Tantou();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("担当が普通に立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$this->shain->setKihonkyu(100);
		$kyuryou = $this->shain->getKyuryou();
		$this->assertEquals(100, $kyuryou);
	}
}
?>
		
tantou.php
<?php
require_once 'shain.php';

/*
 * 担当
 */
class Tantou extends Shain {
	function standup()
	{
		return "担当が普通に立ちました。\n";
	}

	function getKyuryou()
	{
		$kihonkyu = $this->getKihonkyu();
		return $kihonkyu;
	}
}
?>
		
Tests/shuninTests.php
<?php
require_once 'shainTest.php';
require_once 'shunin.php';

class shuninTest extends shainTest {
	function shuninTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Shunin();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("主任がすばやく立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$this->shain->setKihonkyu(100);
		$kyuryou = $this->shain->getKyuryou();
		$this->assertEquals(201, $kyuryou);
	}
}
?>
		
shunin.php
<?php
require_once 'shain.php';

/*
 * 主任
 */
class Shunin extends Shain {
	function standup()
	{
		return "主任がすばやく立ちました。\n";
	}

	function getKyuryou()
	{
		$kihonkyu = $this->getKihonkyu();
		return $kihonkyu * 2 + 1;
	}
}
?>
		
Tests/buchouTest.php
<?php
require_once 'shainTest.php';
require_once 'buchou.php';

class buchouTest extends shainTest {
	function buchouTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Buchou();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("部長がだるそうに立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$this->shain->setKihonkyu(100);
		$kyuryou = $this->shain->getKyuryou();
		$this->assertEquals(300, $kyuryou);
	}
}
?>
		
buchou.php
<?php
require_once 'shain.php';

/*
 * 部長
 */
class Buchou extends Shain {
	function standup()
	{
		return "部長がだるそうに立ちました。\n";
	}

	function getKyuryou()
	{
		$kihonkyu = $this->getKihonkyu();
		return $kihonkyu * 3;
	}
}
?>
		
Tests/torishimariyakuTest.php
<?php
require_once 'shainTest.php';
require_once 'torishimariyaku.php';

class torishimariyakuTest extends PHPUnit_TestCase {
	function torishimariyakuTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shain = new Torishimariyaku();
	}

	function testStandup()
	{
		$ret = $this->shain->standup();
		$this->assertEquals("取締役がふんぞりかえって立ちました。\n", $ret);
	}

	function testKyuryou()
	{
		$this->shain->setKihonkyu(100);
		$kyuryou = $this->shain->getKyuryou();
		$this->assertEquals(402, $kyuryou);
	}
}
?>
		
torishimariyaku.php
<?php
require_once 'shain.php';

/*
 * 取締役
 */
class Torishimariyaku extends Shain {
	function standup()
	{
		return "取締役がふんぞりかえって立ちました。\n";
	}

	function getKyuryou()
	{
		$kihonkyu = $this->getKihonkyu();
		return $kihonkyu * 4 + 2;
	}
}
?>
		
テストを実行します。下の画面のようにグリーンになれば変更は終了です。 [テスト実行結果]

3.3 社長クラスの変更

給料計算の変更と同様に社長クラスのソースも変更します。
ソースは次のようになります。

shachou.php
<?php
require_once 'tantou.php';
require_once 'shunin.php';
require_once 'buchou.php';
require_once 'torishimariyaku.php';

class Shachou {
	function main()
	{
		switch ($_POST["tantou"]) {
		case "担当":
			$shain = new Tantou();
			break;

		case "主任":
			$shain = new Shunin();
			break;

		case "部長":
			$shain = new Buchou();
			break;

		case "取締役":
			$shain = new Torishimariyaku();
			break;

		}


		$ret = "";
		$ret .= $shain->standup();
		$kihonkyu = $_POST["kihonkyu"];
		$shain->setKihonkyu($kihonkyu);
		$kyuryou = $shain->getKyuryou();
		$ret .= "私の給料は" . $kyuryou . "円です。\n";
		return $ret;
	}
}
?>
		
テストを実行します。下の画面のようにグリーンになれば変更は終了です。 [テスト実行結果]

4. ボーナス計算メソッドの追加

4.1 社員クラスの変更

ボーナスを計算するメソッドを追加します。
処理はどの社員でも共通なので社員クラスに追加します。
まずはテストのソースから、

Tests/shainTest.php
<?php
require_once 'PHPUnit.php';

class shainTest extends PHPUnit_TestCase {
	var $shain;

	function testGetBonus()
	{
		$this->shain->setKihonkyu(100);
		$bonus = $this->shain->getBonus();
		$this->assertEquals(300, $bonus);
	}
}
?>
		
これにあわせて社員クラスを変更します。
ソースは次のようになります。
shain.php
<?php
/*
 * 社員用共通クラス
 */
class Shain {
	var $kihonkyu;

	function setKihonkyu($kihonkyu)
	{
		$this->kihonkyu = $kihonkyu;
	}

	function getKihonkyu()
	{
		return $this->kihonkyu;
	}

	function getBonus()
	{
		$kihonkyu = $this->getKihonkyu();
		return $kihonkyu * 3;
	}

	function standup()
	{
	}

	function getKyuryou()
	{
	}
}
?>
		
テストを実行します。下の画面のようにグリーンになれば修正は完了です。
[テストの実行結果]

4.2 社長クラスの変更

社長クラスをボーナスを表示するように変更します。
まずはテストを変更します。
ソースは次のようになります。

Tests/shachouTest.php
<?php
require_once 'PHPUnit.php';
require_once 'shachou.php';

class shachouTest extends PHPUnit_TestCase {
	var $shachou;

	function shachouTest($name)
	{
		$this->PHPUnit_TestCase($name);
	}

	function setup()
	{
		$this->shachou = new Shachou();
	}

	function testStandup()
	{
		$_POST["tantou"] = "担当"; $_POST["kihonkyu"] = "100";
		$ret = $this->shachou->main();
		$this->assertEquals("担当が普通に立ちました。\n私の給料は100円です。\nボーナスは300円です。\n", $ret);

		$_POST["tantou"] = "主任"; $_POST["kihonkyu"] = "100";
		$ret = $this->shachou->main();
		$this->assertEquals("主任がすばやく立ちました。\n私の給料は201円です。\nボーナスは300円です。\n", $ret);

		$_POST["tantou"] = "部長"; $_POST["kihonkyu"] = "100";
		$ret = $this->shachou->main();
		$this->assertEquals("部長がだるそうに立ちました。\n私の給料は300円です。\nボーナスは300円です。\n", $ret);

		$_POST["tantou"] = "取締役"; $_POST["kihonkyu"] = "100";
		$ret = $this->shachou->main();
		$this->assertEquals("取締役がふんぞりかえって立ちました。\n私の給料は402円です。\nボーナスは300円です。\n", $ret);
	}
}
?>
		
次に社長クラスを変更します。
ソースは次のようになります。
shachou.php
<?php
require_once 'tantou.php';
require_once 'shunin.php';
require_once 'buchou.php';
require_once 'torishimariyaku.php';

class Shachou {
	function main()
	{
		switch ($_POST["tantou"]) {
		case "担当":
			$shain = new Tantou();
			break;

		case "主任":
			$shain = new Shunin();
			break;

		case "部長":
			$shain = new Buchou();
			break;

		case "取締役":
			$shain = new Torishimariyaku();
			break;

		}


		$ret = "";
		$ret .= $shain->standup();
		$kihonkyu = $_POST["kihonkyu"];
		$shain->setKihonkyu($kihonkyu);
		$kyuryou = $shain->getKyuryou();
		$ret .= "私の給料は" . $kyuryou . "円です。\n";
		$bonus = $shain->getBonus();
		$ret .= "ボーナスは" . $bonus . "円です。\n";
		return $ret;
	}
}
?>
	
テストを実行します。下の画面のようにグリーンになれば変更は終了です。
[テストの実行結果]

5. 実行

実行して、動作を確認します。テストがすべて通っていれば、正常に動作するはずです。
以下のリンクで動作が確認できます。
[step4 動作デモ]

以上で、step4は終了です。


$Revision: 1 $
Last update: $Date: 2009-03-19 20:17:04 +0900 (譛ィ, 19 3譛 2009) $