Created
February 20, 2013 13:29
-
-
Save ackintosh/4995567 to your computer and use it in GitHub Desktop.
PHPでちょっとしたレジ機能を作る
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$Cart = new Cart(); | |
$Cart->setSetMenu(new SetMenu1()); | |
$Cart->add(new Hamburger(), 2)->add(new Popato(), 2)->add(new Drink(), 2); | |
printf("合計は %d になります。", $Cart->total()); | |
/** | |
* 単品メニュー用の抽象クラス | |
*/ | |
abstract class Menu {} | |
/** | |
* セットメニュー用の抽象クラス | |
*/ | |
abstract class SetMenu | |
{ | |
/** | |
* カート中の商品からセットを検出し、合計に加算 | |
* @access public | |
* @param array $menus カート中の商品 | |
* @param array $total 合計金額 | |
* @return void | |
*/ | |
public abstract function detectAndCalc(&$menus, &$total); | |
} | |
class Hamburger extends Menu | |
{ | |
const PRICE = 250; | |
} | |
class Popato extends Menu | |
{ | |
const PRICE = 200; | |
} | |
class Drink extends Menu | |
{ | |
const PRICE = 150; | |
} | |
class SetMenu1 extends SetMenu | |
{ | |
const PRICE = 550; | |
public function detectAndCalc(&$menus, &$total) | |
{ | |
if ( | |
$menus['Hamburger']['quantity'] >= 1 | |
&& $menus['Popato']['quantity'] >= 1 | |
&& $menus['Drink']['quantity'] >= 1 | |
) { | |
$menus['Hamburger']['quantity']--; | |
$menus['Popato']['quantity']--; | |
$menus['Drink']['quantity']--; | |
$total += self::PRICE; | |
$this->detectAndCalc($menus, $total); | |
} else { | |
return; | |
} | |
} | |
} | |
class Cart | |
{ | |
private $menus = array(); | |
private $setMenus = array(); | |
/** | |
* カートに商品を追加 | |
* @access public | |
* @param Menu $menu 商品 | |
* @param int $quantity 購入数 | |
* @return $this | |
*/ | |
public function add(Menu $menu, $quantity) | |
{ | |
if (!is_int($quantity) || !($quantity > 0)) return false; | |
$this->menus[get_class($menu)]['menu'] = $menu; | |
@$this->menus[get_class($menu)]['quantity'] += $quantity; | |
return $this; | |
} | |
/** | |
* カートにセットメニューを設定する | |
* @access public | |
* @param SetMenu $setMenu セットメニュー | |
* @return $this | |
*/ | |
public function setSetMenu(SetMenu $setMenu) | |
{ | |
$this->setMenus[] = $setMenu; | |
return $this; | |
} | |
/** | |
* 合計金額を返す | |
* @access public | |
* @return int $total 合計金額 | |
*/ | |
public function total() | |
{ | |
$menus = $this->menus; | |
$total = 0; | |
// セットメニューの計算 | |
foreach ($this->setMenus as $s) { | |
$s->detectAndCalc($menus, $total); | |
} | |
// 単品商品の計算 | |
foreach ($menus as $m) { | |
$total += $m['menu']::PRICE * $m['quantity']; | |
} | |
return $total; | |
} | |
} | |
/* | |
問題その1「PHPでちょっとしたレジ機能を作る」 | |
あなたはあるプロジェクトに参加することになりました。 | |
前任者が作ったハンバーガーショップの合計金額計算を行なう簡単なコードがあります。 | |
先輩社員からそのコードに対し、仕様変更が行なわれることを伝えられました。 | |
・既存の仕様 | |
ハンバーガーショップでの買い物の計算をするプログラム | |
ハンバーガー 250 円、ポテト 200 円、ドリンク 150 円で販売されている | |
・メニューのイメージ | |
-------------------- | |
ハンバーガー 250円 ○個 | |
ポテト 200円 ○個 | |
ドリンク 150円 ○個 | |
-------------------- | |
合計 ○○○円 | |
-------------------- | |
・仕様変更の内容 | |
ハンバーガー、ポテト、ドリンクをセットで頼むとセットの金額が 550 円になる | |
先輩社員「今は単品価格がそれぞれ、ハンバーガー250円、ポテト200円、ドリンク150円なんだ」 | |
あなた「それぞれの注文数にあわせて合計金額を計算してるんですね」 | |
先輩社員「そう。そして今度セットメニューを導入し、ハンバーガーとポテトとドリンクで550円になる」 | |
あなた「それぞれふたつずつ買うと1,100円ということですね」 | |
先輩社員「そうだね。前任者が作ったときはセットメニューを導入するなんてことは思いもよらなかったんだと思う」 | |
あなた「分かりました。今回の仕様変更を反映したコードにすれば良いんですね!」 | |
先輩社員「頼んだよ。ちなみに今後は来月入る新人の子にメンテナンスさせるからそのつもりで直してくれると助かる」 | |
あなた「他に考えておくことはありますか?」 | |
先輩社員「そうだね。今後も仕様変更がいくつかると思うんだ。だから、今は関数となっているところをクラスにして、変更やテストがしやすいようにしてね」 | |
【課題】 | |
仕様変更後のPHPコードを作成してください。 | |
どのような点に気をつけてコーディングしたかも説明として追加してください。 | |
コード内には適宜コメントを挿入してください。 | |
また、計算呼び出し部分の変更も可能です。 | |
・前任者が作成したコード | |
function calc($hamburger, $potato, $drink) | |
{ | |
return $hamburger * 250 + $potato * 200 + $drink * 150; | |
} | |
// 計算呼び出し部分 | |
printf(“合計は %d になります。”, calc($hamburger, $potato, $drink)); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment