商品の料金計算には、バリューオブジェクトが便利!
はじめに
みなさま、バリューオブジェクト(ValueObject, 値オブジェクト)をご存知でしょうか。
バリューオブジェクトとは、クラスや構造体を用いて値を保持するという設計手法を指します。
クラスや構造体を用いて値を保持することで、開発のしやすさが劇的に向上します!
本日は、特に「商品の料金計算」を実装する際にバリューオブジェクトを使うといいよ、という話をします。
参考になれば嬉しいです!
実装例
先に実装例をお見せします。
Before: バリューオブジェクトを使わない例
バリューオブジェクトを使わない例const UNIT_PRICE = 100; // 商品1の単価 const TAX_RATE = 10; // 税率 ... // 中略 // 商品数 $count = 10; // 税抜金額 $chargeExcludeTax = $count * self::UNIT_PRICE; // 税額 $tax = $chargeExcludeTax / self::TAX_RATE; // 税込金額 $chargeIncludeTax = $chargeExcludeTax + $tax; // それぞれの値ごとに変数がバラバラなので、管理が大変・・・ // 後の処理で、意図しない値に更新されてしまうかも・・・ // 間違って、税込金額にまた税を足してしまう例 $chargeIncludeTax = $chargeIncludeTax * 1.1;
保守が大変な辛いコードになっております。
上記のような処理を、バリューオブジェクトを使って実装してみます。
After: バリューオブジェクトを使った例
バリューオブジェクトを使った例/** * 商品1 の 個数を受け取り 税抜金額・税額・税込金額を計算する */ class Service1ChargeValue { const UNIT_PRICE = 100; // 商品1の単価 const TAX_RATE = 10; // 税率 public $chargeExcludeTax; public $tax; public $chargeIncludeTax; public function __construct( int $count ) { // 税抜金額 $this->chargeExcludeTax = $count * self::UNIT_PRICE; // 税額 $this->tax = $this->chargeExcludeTax / self::TAX_RATE; // 税込金額 $this->chargeIncludeTax = $this->chargeExcludeTax + $this->tax; } } $service_1 = new Service1ChargeValue(10); echo '税抜金額: ' . $service_1->chargeExcludeTax . PHP_EOL; echo '税額: ' . $service_1->tax . PHP_EOL; echo '税込金額: ' . $service_1->chargeIncludeTax . PHP_EOL; // 税抜金額: 1000 // 税額: 100 // 税込金額: 1100
とてもスッキリしました!
税込金額や税額などが、ひとつのオブジェクトにまとまっているため、非常に扱いやすくなります。
また、getter
メソッドを追加することで、オブジェクト全体をイミュータブル(変更ができない状態)にすることも可能です。
バリューオブジェクトを使った例(イミュータブル版)class Service1ChargeValue { const UNIT_PRICE = 100; // 商品1の単価 const TAX_RATE = 10; // 税率 private $chargeExcludeTax; private $tax; private $chargeIncludeTax; public function __construct( int $count ) { // 税抜金額 $this->chargeExcludeTax = $count * self::UNIT_PRICE; // 税額 $this->tax = $this->chargeExcludeTax / self::TAX_RATE; // 税込金額 $this->chargeIncludeTax = $this->chargeExcludeTax + $this->tax; } public function getChargeExcludeTax(): int { return $this->chargeExcludeTax; } public function getTax(): int { return $this->tax; } public function getChargeIncludeTax(): int { return $this->chargeIncludeTax; } } $service_1 = new Service1ChargeValue(10); echo '税抜金額: ' . $service_1->getChargeExcludeTax() . PHP_EOL; echo '税額: ' . $service_1->getTax() . PHP_EOL; echo '税込金額: ' . $service_1->getChargeIncludeTax() . PHP_EOL; // 税抜金額: 1000 // 税額: 100 // 税込金額: 1100
おわりに
オブジェクトをイミュータブルにすることで、プロパティが意図しない値へと更新される心配がなくなるため、保守性がさらに高まります!
みなさまも機会があればぜひバリューオブジェクトを使ってみてください。