Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ShoppingService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ShoppingService, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
41 | class ShoppingService |
||
|
|||
42 | { |
||
43 | /** @var \Eccube\Application */ |
||
44 | public $app; |
||
45 | |||
46 | /** @var \Eccube\Service\CartService */ |
||
47 | protected $cartService; |
||
48 | |||
49 | /** @var \Eccube\Service\OrderService */ |
||
50 | protected $orderService; |
||
51 | |||
52 | /** @var \Eccube\Entity\BaseInfo */ |
||
53 | protected $BaseInfo; |
||
54 | |||
55 | /** @var \Doctrine\ORM\EntityManager */ |
||
56 | protected $em; |
||
57 | |||
58 | 44 | public function __construct(Application $app, $cartService, $orderService) |
|
65 | |||
66 | /** |
||
67 | * セッションにセットされた受注情報を取得 |
||
68 | * |
||
69 | * @param null $status |
||
70 | * @return null|object |
||
71 | */ |
||
72 | 17 | public function getOrder($status = null) |
|
95 | 3 | ||
96 | /** |
||
97 | * 非会員情報を取得 |
||
98 | * |
||
99 | * @param $sesisonKey |
||
100 | * @return $Customer|null |
||
101 | */ |
||
102 | public function getNonMember($sesisonKey) |
||
116 | |||
117 | /** |
||
118 | * 受注情報を作成 |
||
119 | * |
||
120 | * @param $Customer |
||
121 | * @return \Eccube\Entity\Order |
||
122 | */ |
||
123 | public function createOrder($Customer) |
||
138 | 16 | ||
139 | /** |
||
140 | * 仮受注情報作成 |
||
141 | * |
||
142 | * @param $Customer |
||
143 | * @param $preOrderId |
||
144 | * @return mixed |
||
145 | * @throws \Doctrine\ORM\NoResultException |
||
146 | * @throws \Doctrine\ORM\NonUniqueResultException |
||
147 | */ |
||
148 | public function registerPreOrder(Customer $Customer, $preOrderId) |
||
209 | |||
210 | 16 | /** |
|
211 | * 受注情報を作成 |
||
212 | 16 | * @param $Customer |
|
213 | * @return \Eccube\Entity\Order |
||
214 | */ |
||
215 | public function getNewOrder(Customer $Customer) |
||
222 | |||
223 | |||
224 | 16 | /** |
|
225 | 16 | * 受注情報を作成 |
|
226 | * @return \Eccube\Entity\Order |
||
227 | */ |
||
228 | public function newOrder() |
||
234 | |||
235 | /** |
||
236 | 16 | * 受注情報を作成 |
|
237 | * |
||
238 | * @param \Eccube\Entity\Order $Order |
||
239 | * @param \Eccube\Entity\Customer|null $Customer |
||
240 | * @return \Eccube\Entity\Order |
||
241 | */ |
||
242 | public function copyToOrderFromCustomer(Order $Order, Customer $Customer = null) |
||
276 | |||
277 | |||
278 | 16 | /** |
|
279 | 16 | * 配送業者情報を取得 |
|
280 | * |
||
281 | * @return array |
||
282 | */ |
||
283 | public function getDeliveriesCart() |
||
291 | |||
292 | /** |
||
293 | * 配送業者情報を取得 |
||
294 | * |
||
295 | * @param Order $Order |
||
296 | * @return array |
||
297 | */ |
||
298 | public function getDeliveriesOrder(Order $Order) |
||
306 | |||
307 | /** |
||
308 | * 配送業者情報を取得 |
||
309 | * |
||
310 | * @param $productTypes |
||
311 | * @return array |
||
312 | */ |
||
313 | public function getDeliveries($productTypes) |
||
333 | |||
334 | |||
335 | /** |
||
336 | * お届け先情報を作成 |
||
337 | * |
||
338 | 10 | * @param Order $Order |
|
339 | * @param Customer $Customer |
||
340 | * @param $deliveries |
||
341 | * @return Order |
||
342 | */ |
||
343 | public function getNewShipping(Order $Order, Customer $Customer, $deliveries) |
||
367 | |||
368 | /** |
||
369 | * お届け先情報を作成 |
||
370 | * |
||
371 | * @param \Eccube\Entity\Shipping $Shipping |
||
372 | * @param \Eccube\Entity\Customer|null $Customer |
||
373 | 16 | * @return \Eccube\Entity\Shipping |
|
374 | 16 | */ |
|
375 | public function copyToShippingFromCustomer(Shipping $Shipping, Customer $Customer = null) |
||
376 | { |
||
377 | if (is_null($Customer)) { |
||
378 | return $Shipping; |
||
379 | } |
||
380 | |||
381 | $CustomerAddress = $this->app['eccube.repository.customer_address']->findOneBy( |
||
382 | array('Customer' => $Customer), |
||
383 | 17 | array('id' => 'ASC') |
|
384 | ); |
||
385 | |||
386 | 1 | if (!is_null($CustomerAddress)) { |
|
387 | $Shipping |
||
388 | ->setName01($CustomerAddress->getName01()) |
||
389 | 16 | ->setName02($CustomerAddress->getName02()) |
|
390 | 16 | ->setKana01($CustomerAddress->getKana01()) |
|
391 | 16 | ->setKana02($CustomerAddress->getKana02()) |
|
392 | ->setCompanyName($CustomerAddress->getCompanyName()) |
||
393 | ->setTel01($CustomerAddress->getTel01()) |
||
394 | ->setTel02($CustomerAddress->getTel02()) |
||
395 | ->setTel03($CustomerAddress->getTel03()) |
||
396 | ->setFax01($CustomerAddress->getFax01()) |
||
397 | ->setFax02($CustomerAddress->getFax02()) |
||
398 | ->setFax03($CustomerAddress->getFax03()) |
||
399 | ->setZip01($CustomerAddress->getZip01()) |
||
400 | ->setZip02($CustomerAddress->getZip02()) |
||
401 | ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02()) |
||
402 | ->setPref($CustomerAddress->getPref()) |
||
403 | ->setAddr01($CustomerAddress->getAddr01()) |
||
404 | ->setAddr02($CustomerAddress->getAddr02()); |
||
405 | } else { |
||
406 | $Shipping |
||
407 | ->setName01($Customer->getName01()) |
||
408 | ->setName02($Customer->getName02()) |
||
409 | ->setKana01($Customer->getKana01()) |
||
410 | ->setKana02($Customer->getKana02()) |
||
411 | ->setCompanyName($Customer->getCompanyName()) |
||
412 | ->setTel01($Customer->getTel01()) |
||
413 | ->setTel02($Customer->getTel02()) |
||
414 | ->setTel03($Customer->getTel03()) |
||
415 | ->setFax01($Customer->getFax01()) |
||
416 | ->setFax02($Customer->getFax02()) |
||
417 | ->setFax03($Customer->getFax03()) |
||
418 | ->setZip01($Customer->getZip01()) |
||
419 | ->setZip02($Customer->getZip02()) |
||
420 | ->setZipCode($Customer->getZip01().$Customer->getZip02()) |
||
421 | ->setPref($Customer->getPref()) |
||
422 | ->setAddr01($Customer->getAddr01()) |
||
423 | ->setAddr02($Customer->getAddr02()); |
||
424 | } |
||
425 | |||
426 | return $Shipping; |
||
427 | } |
||
428 | |||
429 | |||
430 | /** |
||
431 | * 受注明細情報、配送商品情報を作成 |
||
432 | 14 | * |
|
433 | * @param Order $Order |
||
434 | 16 | * @return Order |
|
435 | 17 | */ |
|
436 | public function getNewDetails(Order $Order) |
||
459 | |||
460 | /** |
||
461 | * 受注明細情報を作成 |
||
462 | * |
||
463 | * @param Product $Product |
||
464 | * @param ProductClass $ProductClass |
||
465 | 16 | * @param $quantity |
|
466 | * @return \Eccube\Entity\OrderDetail |
||
467 | 16 | */ |
|
468 | public function getNewOrderDetail(Product $Product, ProductClass $ProductClass, $quantity) |
||
496 | |||
497 | /** |
||
498 | * 配送商品情報を作成 |
||
499 | * |
||
500 | * @param Order $Order |
||
501 | * @param Product $Product |
||
502 | * @param ProductClass $ProductClass |
||
503 | 16 | * @param $quantity |
|
504 | 16 | * @return \Eccube\Entity\ShipmentItem |
|
505 | */ |
||
506 | public function getNewShipmentItem(Order $Order, Product $Product, ProductClass $ProductClass, $quantity) |
||
558 | |||
559 | /** |
||
560 | * お届け先ごとの送料合計を取得 |
||
561 | * |
||
562 | * @param $shippings |
||
563 | * @return int |
||
564 | */ |
||
565 | public function getShippingDeliveryFeeTotal($shippings) |
||
574 | |||
575 | /** |
||
576 | 16 | * 商品ごとの配送料を取得 |
|
577 | * |
||
578 | 16 | * @param Shipping $Shipping |
|
579 | * @return int |
||
580 | */ |
||
581 | public function getProductDeliveryFee(Shipping $Shipping) |
||
590 | |||
591 | /** |
||
592 | * 住所などの情報が変更された時に金額の再計算を行う |
||
593 | 14 | * |
|
594 | * @param Order $Order |
||
595 | 14 | * @return Order |
|
596 | */ |
||
597 | public function getAmount(Order $Order) |
||
620 | |||
621 | /** |
||
622 | * 配送料金の設定 |
||
623 | * |
||
624 | * @param Shipping $Shipping |
||
625 | * @param Delivery|null $Delivery |
||
626 | */ |
||
627 | public function setShippingDeliveryFee(Shipping $Shipping, Delivery $Delivery = null) |
||
647 | |||
648 | /** |
||
649 | * 配送料無料条件(合計金額)の条件を満たしていれば配送料金を0に設定 |
||
650 | * |
||
651 | * @param Order $Order |
||
652 | 15 | */ |
|
653 | View Code Duplication | public function setDeliveryFreeAmount(Order $Order) |
|
669 | |||
670 | /** |
||
671 | * 配送料無料条件(合計数量)の条件を満たしていれば配送料金を0に設定 |
||
672 | * |
||
673 | * @param Order $Order |
||
674 | */ |
||
675 | View Code Duplication | public function setDeliveryFreeQuantity(Order $Order) |
|
691 | |||
692 | |||
693 | /** |
||
694 | * 商品公開ステータスチェック、在庫チェック、購入制限数チェックを行い、在庫情報をロックする |
||
695 | * |
||
696 | * @param $em トランザクション制御されているEntityManager |
||
697 | * @param Order $Order 受注情報 |
||
698 | * @return bool true : 成功、false : 失敗 |
||
699 | */ |
||
700 | public function isOrderProduct($em, \Eccube\Entity\Order $Order) |
||
737 | |||
738 | /** |
||
739 | 1 | * 受注情報、お届け先情報の更新 |
|
740 | * |
||
741 | * @param Order $Order 受注情報 |
||
742 | * @param $data フォームデータ |
||
743 | */ |
||
744 | 1 | public function setOrderUpdate(Order $Order, $data) |
|
784 | |||
785 | 5 | ||
786 | /** |
||
787 | * 在庫情報の更新 |
||
788 | * |
||
789 | * @param $em トランザクション制御されているEntityManager |
||
790 | * @param Order $Order 受注情報 |
||
791 | */ |
||
792 | public function setStockUpdate($em, Order $Order) |
||
813 | |||
814 | |||
815 | /** |
||
816 | * 会員情報の更新 |
||
817 | * |
||
818 | * @param Order $Order 受注情報 |
||
819 | 1 | * @param Customer $user ログインユーザ |
|
820 | */ |
||
821 | public function setCustomerUpdate(Order $Order, Customer $user) |
||
836 | |||
837 | |||
838 | /** |
||
839 | * 支払方法選択の表示設定 |
||
840 | * |
||
841 | * @param $payments 支払選択肢情報 |
||
842 | 3 | * @param $subTotal 小計 |
|
843 | * @return array |
||
844 | */ |
||
845 | public function getPayments($payments, $subTotal) |
||
862 | |||
863 | /** |
||
864 | * お届け日を取得 |
||
865 | * |
||
866 | * @param Order $Order |
||
867 | * @return array |
||
868 | 10 | */ |
|
869 | public function getFormDeliveryDates(Order $Order) |
||
870 | 10 | { |
|
871 | |||
872 | // お届け日の設定 |
||
873 | $minDate = 0; |
||
874 | $deliveryDateFlag = false; |
||
875 | |||
876 | // 配送時に最大となる商品日数を取得 |
||
877 | foreach ($Order->getOrderDetails() as $detail) { |
||
878 | $deliveryDate = $detail->getProductClass()->getDeliveryDate(); |
||
879 | if (!is_null($deliveryDate)) { |
||
880 | if ($minDate < $deliveryDate->getValue()) { |
||
881 | $minDate = $deliveryDate->getValue(); |
||
882 | } |
||
883 | 10 | // 配送日数が設定されている |
|
884 | $deliveryDateFlag = true; |
||
885 | } |
||
886 | } |
||
887 | |||
888 | // 配達最大日数期間を設定 |
||
889 | $deliveryDates = array(); |
||
890 | |||
891 | // 配送日数が設定されている |
||
892 | if ($deliveryDateFlag) { |
||
893 | 4 | $period = new \DatePeriod( |
|
894 | new \DateTime($minDate.' day'), |
||
895 | new \DateInterval('P1D'), |
||
896 | new \DateTime($minDate + $this->app['config']['deliv_date_end_max'].' day') |
||
897 | 4 | ); |
|
898 | 4 | ||
899 | foreach ($period as $day) { |
||
900 | $deliveryDates[$day->format('Y/m/d')] = $day->format('Y/m/d'); |
||
901 | 4 | } |
|
902 | } |
||
903 | |||
904 | return $deliveryDates; |
||
905 | } |
||
906 | |||
907 | /** |
||
908 | 1 | * 支払方法を取得 |
|
909 | * |
||
910 | * @param $deliveries |
||
911 | * @param Order $Order |
||
912 | * @return array |
||
913 | 4 | */ |
|
914 | public function getFormPayments($deliveries, Order $Order) |
||
933 | |||
934 | /** |
||
935 | * お届け先ごとにFormを作成 |
||
936 | * |
||
937 | * @param Order $Order |
||
938 | * @return \Symfony\Component\Form\Form |
||
939 | 5 | * @deprecated since 3.0, to be removed in 3.1 |
|
940 | */ |
||
941 | View Code Duplication | public function getShippingForm(Order $Order) |
|
966 | |||
967 | /** |
||
968 | 3 | * お届け先ごとにFormBuilderを作成 |
|
969 | * |
||
970 | * @param Order $Order |
||
971 | * @return \Symfony\Component\Form\FormBuilderInterface |
||
972 | */ |
||
973 | View Code Duplication | public function getShippingFormBuilder(Order $Order) |
|
996 | } |
||
997 |