用 chain of responsibility 模式實作卡路里計算公式
不過卡路里計算公式只使用了「性別」和「活動量等級」二個條件,應該不需要特地使用 design pattern 才是
實務上不需要弄得這麼複雜,當作練習就好
參考
用 chain of responsibility 模式實作卡路里計算公式
不過卡路里計算公式只使用了「性別」和「活動量等級」二個條件,應該不需要特地使用 design pattern 才是
實務上不需要弄得這麼複雜,當作練習就好
參考
<?php | |
use App\Models\Member; | |
abstract class AbstractCalculator | |
{ | |
/** @var self */ | |
private $next = null; | |
/** | |
* @param self $next | |
* @return void | |
*/ | |
public function setNext(CaloriesCalculator $next) | |
{ | |
$this->next = $next; | |
} | |
/** | |
* @param \App\Models\Member $member | |
* @return void|\App\Models\Member | |
*/ | |
public function next(Member $member) | |
{ | |
if ($this->next instanceof CaloriesCalculator) { | |
return $this->next->calculate($member); | |
} | |
return $member; | |
} | |
/** | |
* @param \App\Models\Member $member | |
* @return void | |
*/ | |
abstract public function calculate(Member $member); | |
} |
<?php | |
use App\Models\Member; | |
class ActivityCalculator extends CaloriesCalculator | |
{ | |
public function calculate(Member $member) | |
{ | |
$ratio = 1; | |
if ($member->activity === 1) { // 低活動量 | |
$ratio = 1.2; | |
} elseif ($member->activity === 2) { // 中活動量 | |
$ratio = 1.375; | |
} elseif ($member->activity === 3) { // 高活動量 | |
$ratio = 1.55; | |
} else { | |
return $this->next($member); | |
} | |
$member->suggest_kcal *= $ratio; | |
return $this->next($member); | |
} | |
} |
<?php | |
use App\Models\Member; | |
use Illuminate\Support\Carbon; | |
class AgeCalculator extends CaloriesCalculator | |
{ | |
public function calculate(Member $member) | |
{ | |
$ratio = 1; | |
if ($member->isMale()) { | |
$ratio = 6.8; | |
} elseif ($member->isFemale()) { | |
$ratio = 4.7; | |
} else { | |
return $this->next($member); | |
} | |
$age = Carbon::parse($member->birthday)->age; | |
$member->suggest_kcal -= ($ratio * $age); | |
return $this->next($member); | |
} | |
} |
<?php | |
use App\Models\Member; | |
class BmrCalculator extends CaloriesCalculator | |
{ | |
public function calculate(Member $member) | |
{ | |
if ($member->isMale()) { | |
$member->suggest_kcal += 66; | |
} elseif ($member->isFemale()) { | |
$member->suggest_kcal += 665; | |
} else { | |
return $this->next($member); | |
} | |
return $this->next($member); | |
} | |
} |
<?php | |
$step1 = new HeightCalculator(); | |
$step2 = new WeightCalculator(); | |
$step3 = new AgeCalculator(); | |
$step4 = new BmrCalculator(); | |
$step5 = new ActivityCalculator(); | |
// 基礎代謝率 Basal metabolic rate | |
$step1->setNext($step2); | |
$step2->setNext($step3); | |
$step3->setNext($step4); | |
$memberWithBmr = $step1->calculate($member); | |
// 每日建議攝取熱量 Recommended daily calories | |
$step4->setNext($step5); | |
$memberWithRdc = $step4->calculate($memberWithBmr); |
<?php | |
use App\Models\Member; | |
class HeightCalculator extends AbstractCalculator | |
{ | |
public function calculate(Member $member) | |
{ | |
$ratio = 1; | |
if ($member->isMale()) { | |
$ratio = 13.7; | |
} elseif ($member->isFemale()) { | |
$ratio = 9.6; | |
} else { | |
return $this->next($member); | |
} | |
$member->suggest_kcal += ($ratio * $member->height); | |
return $this->next($member); | |
} | |
} |
<?php | |
use Illuminate\Database\Eloquent\Model; | |
class Member extends Model | |
{ | |
public function isMale() | |
{ | |
// ... | |
} | |
public function isFemale() | |
{ | |
// ... | |
} | |
} |
<?php | |
use App\Models\Member; | |
class WeightCalculator extends AbstractCalculator | |
{ | |
public function calculate(Member $member) | |
{ | |
$ratio = 1; | |
if ($member->isMale()) { | |
$ratio = 5; | |
} elseif ($member->isFemale()) { | |
$ratio = 1.8; | |
} else { | |
return $this->next($member); | |
} | |
$member->suggest_kcal += ($ratio * $member->weight); | |
return $this->next($member); | |
} | |
} |