Last active
November 28, 2016 07:01
-
-
Save nanasess/b213bffe4c8f05390f5c6f91b1568887 to your computer and use it in GitHub Desktop.
単価集計の案
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 | |
class ShopingController | |
{ | |
public function confirm(Request $request) | |
{ | |
// 単価集計 | |
// 集計済みの Order を返す. | |
// 管理画面でも同じインターフェイスを使用可能 | |
$Order = $app['eccube.service.calculator']->calculate(); | |
$orderService->setOrderUpdate($em, $Order, $formData); | |
// 在庫情報を更新 | |
$orderService->setStockUpdate($em, $Order); | |
$paymentService = $app['eccube.service.payment']; | |
$paymentService->setOrder($Order); | |
// 支払実行 | |
$paymentMethod = $app['payment.method']; | |
$paymentMethod->setPayment($Order->getPayment()); | |
$orderResult = $paymentService->doCheckout($paymentMethod); | |
/** これを関数型言語っぽく書きたい */ | |
$Order = $OrderService->doCheckout( | |
// これだとプラッガブルではないので、 | |
// プラッガブルにするには Strategy パターンしか思いつかない... | |
$Calculate | |
->execute($OrderDetails) | |
->execute($Shipping) | |
->execute($Point) | |
); | |
if (!$orderResult->isSuccess()) { | |
// 在庫戻す | |
$em->getConnection()->rollback(); | |
return $app->redirect($app->url('shopping_error')); | |
} | |
return $app->redirect($app->url('shopping_complete')); | |
} | |
} | |
/** カスタマイズ開発者が実装するのはここから */ | |
class PaymentCash implements PaymentMethod | |
{} | |
class PaymentBank implements PaymentMethod | |
{} | |
class PaymentCreditCard implements PaymentMethod | |
{ | |
// 決済処理中に在庫情報をロックするのはイケてないので, | |
// 失敗したら在庫を戻す等の処理が必要 | |
// 画面遷移を伴うものは Delegate する。 | |
// 完了処理は共通化しておく | |
} | |
class Coupon implements CalculateStrategy | |
{ | |
public function execute(array &$OrderDetails) | |
{ | |
$point = -100; | |
$OrderDetail = new OrderDetail(); | |
$OrderDetail->setProductName('利用クーポン') | |
->setPrice($point); | |
$OrderDetails[] = $OrderDetail; | |
} | |
} | |
class Cart implements CalculateStrategy | |
{ | |
public function execute(array &$OrderDetails) | |
{ | |
$point = -100; | |
$OrderDetail = new OrderDetail(); | |
$OrderDetail->setProductName('利用クーポン') | |
->setPrice($point); | |
$OrderDetails[] = $OrderDetail; | |
} | |
} | |
class Batch implements CalculateStrategy | |
{ | |
public function execute(array &$OrderDetails) | |
{ | |
$point = -100; | |
$OrderDetail = new OrderDetail(); | |
$OrderDetail->setProductName('利用クーポン') | |
->setPrice($point); | |
$OrderDetails[] = $OrderDetail; | |
} | |
} | |
/** | |
* 利用ポイント | |
*/ | |
class UsePoint implements CalculateStrategy | |
{ | |
public function execute(array &$OrderDetails) | |
{ | |
$point = -100; | |
$OrderDetail = new OrderDetail(); | |
$OrderDetail->setProductName('利用ポイント') | |
->setPrice($point); | |
$OrderDetails[] = $OrderDetail; | |
} | |
} | |
/** | |
* 送料計算クラス | |
* | |
* @PointCut(Order->total <= 3000) | |
*/ | |
class Shipping implements CalculateStrategy | |
{ | |
protected $Pref; | |
protected $Shippings; | |
public function execute(array &$OrderDetails) | |
{ | |
$shipping_fee = 0; | |
foreach ($Shippings as $Shipping) { | |
$shipping_fee += $Shipping->getDeliveryFee(); | |
} | |
$OrderDetail = new OrderDetail(); | |
$OrderDetail->setProductName('送料') | |
->setPrice($shipping_fee); | |
$OrderDetails[] = $OrderDetail; | |
} | |
} | |
/** カスタマイズ開発者が実装するのはここまで */ | |
// 今風にやるなら Closure | |
interface CalculateStrategy | |
{ | |
public function execute(array $OrderDetails); | |
} | |
class CalculateContext | |
{ | |
protected $Order; | |
protected $OrderDetails = []; | |
// $app['eccube.calculate.strategies'] に DI する | |
protected $CalculateStrategies = []; | |
public function executeCalculator() | |
{ | |
foreach ($CalculateStrategies as $Strategy) { | |
$strategy->execute($this->OrderDetails); | |
} | |
return $this->calculateOrder($this->Order, $this->OrderDetails); | |
} | |
public function calculateOrder(Order $Order, array $OrderDetails) | |
{ | |
// OrderDetails の計算結果を Order にセットする | |
return $Order; | |
} | |
} | |
class CalculateService | |
{ | |
protected $Customer; | |
protected $Order; | |
protected $ProductClasses = []; | |
protected $Deliveries = []; | |
protected $Payment; | |
protected $CalculateContext; | |
public function addCalculator(CalculateStrategy $strategy) | |
{ | |
$CalculateContext->CalculateStrategy[] = $strategy; | |
} | |
public function calculate() | |
{ | |
$Order = $CalculateContext->executeCalculator(); | |
return $Order; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment