Complex classes like PromotionContext 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 PromotionContext, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
35 | final class PromotionContext implements Context |
||
36 | { |
||
37 | /** |
||
38 | * @var SharedStorageInterface |
||
39 | */ |
||
40 | private $sharedStorage; |
||
41 | |||
42 | /** |
||
43 | * @var PromotionActionFactoryInterface |
||
44 | */ |
||
45 | private $actionFactory; |
||
46 | |||
47 | /** |
||
48 | * @var PromotionCouponFactoryInterface |
||
49 | */ |
||
50 | private $couponFactory; |
||
51 | |||
52 | /** |
||
53 | * @var PromotionRuleFactoryInterface |
||
54 | */ |
||
55 | private $ruleFactory; |
||
56 | |||
57 | /** |
||
58 | * @var TestPromotionFactoryInterface |
||
59 | */ |
||
60 | private $testPromotionFactory; |
||
61 | |||
62 | /** |
||
63 | * @var PromotionRepositoryInterface |
||
64 | */ |
||
65 | private $promotionRepository; |
||
66 | |||
67 | /** |
||
68 | * @var ObjectManager |
||
69 | */ |
||
70 | private $objectManager; |
||
71 | |||
72 | /** |
||
73 | * @param SharedStorageInterface $sharedStorage |
||
74 | * @param PromotionActionFactoryInterface $actionFactory |
||
75 | * @param PromotionCouponFactoryInterface $couponFactory |
||
76 | * @param PromotionRuleFactoryInterface $ruleFactory |
||
77 | * @param TestPromotionFactoryInterface $testPromotionFactory |
||
78 | * @param PromotionRepositoryInterface $promotionRepository |
||
79 | * @param ObjectManager $objectManager |
||
80 | */ |
||
81 | public function __construct( |
||
98 | |||
99 | /** |
||
100 | * @Given there is a promotion :promotionName |
||
101 | * @Given there is a promotion :promotionName identified by :promotionCode code |
||
102 | */ |
||
103 | public function thereIsPromotion($promotionName, $promotionCode = null) |
||
116 | |||
117 | /** |
||
118 | * @Given /^there is a promotion "([^"]+)" with priority ([^"]+)$/ |
||
119 | */ |
||
120 | public function thereIsAPromotionWithPriority($promotionName, $priority) |
||
131 | |||
132 | /** |
||
133 | * @Given /^there is an exclusive promotion "([^"]+)"(?:| with priority ([^"]+))$/ |
||
134 | */ |
||
135 | public function thereIsAnExclusivePromotionWithPriority($promotionName, $priority = 0) |
||
147 | |||
148 | /** |
||
149 | * @Given there is a promotion :promotionName limited to :usageLimit usages |
||
150 | */ |
||
151 | public function thereIsPromotionLimitedToUsages($promotionName, $usageLimit) |
||
160 | |||
161 | /** |
||
162 | * @Given the store has promotion :promotionName with coupon :couponCode |
||
163 | * @Given the store has a promotion :promotionName with a coupon :couponCode that is limited to :usageLimit usages |
||
164 | */ |
||
165 | public function thereIsPromotionWithCoupon($promotionName, $couponCode, $usageLimit = null) |
||
183 | |||
184 | /** |
||
185 | * @Given /^(this promotion) has already expired$/ |
||
186 | */ |
||
187 | public function thisPromotionHasExpired(PromotionInterface $promotion) |
||
193 | |||
194 | /** |
||
195 | * @Given /^(this promotion) expires tomorrow$/ |
||
196 | */ |
||
197 | public function thisPromotionExpiresTomorrow(PromotionInterface $promotion) |
||
203 | |||
204 | /** |
||
205 | * @Given /^(this promotion) has started yesterday$/ |
||
206 | */ |
||
207 | public function thisPromotionHasStartedYesterday(PromotionInterface $promotion) |
||
213 | |||
214 | /** |
||
215 | * @Given /^(this promotion) starts tomorrow$/ |
||
216 | */ |
||
217 | public function thisPromotionStartsTomorrow(PromotionInterface $promotion) |
||
223 | |||
224 | /** |
||
225 | * @Given /^(this coupon) has already expired$/ |
||
226 | */ |
||
227 | public function thisCouponHasExpired(PromotionCouponInterface $coupon) |
||
233 | |||
234 | /** |
||
235 | * @Given /^(this coupon) expires tomorrow$/ |
||
236 | */ |
||
237 | public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon) |
||
243 | |||
244 | /** |
||
245 | * @Given /^(this coupon) has already reached its usage limit$/ |
||
246 | */ |
||
247 | public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon) |
||
254 | |||
255 | /** |
||
256 | * @Given /^(this coupon) can be used (\d+) times?$/ |
||
257 | */ |
||
258 | public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, $usageLimit) |
||
264 | |||
265 | /** |
||
266 | * @Given /^(this coupon) can be used twice per customer$/ |
||
267 | */ |
||
268 | public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon) |
||
274 | |||
275 | /** |
||
276 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/ |
||
277 | */ |
||
278 | public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount) |
||
282 | |||
283 | /** |
||
284 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/ |
||
285 | */ |
||
286 | public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel( |
||
303 | |||
304 | /** |
||
305 | * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/ |
||
306 | */ |
||
307 | public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount) |
||
311 | |||
312 | /** |
||
313 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/ |
||
314 | */ |
||
315 | public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast( |
||
324 | |||
325 | /** |
||
326 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/ |
||
327 | */ |
||
328 | public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast( |
||
338 | |||
339 | /** |
||
340 | * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/ |
||
341 | */ |
||
342 | public function itGivesOffOnEveryItemWhenItemTotalExceeds( |
||
352 | |||
353 | /** |
||
354 | * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/ |
||
355 | */ |
||
356 | public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount) |
||
363 | |||
364 | /** |
||
365 | * @Given /^([^"]+) gives free shipping to every order$/ |
||
366 | */ |
||
367 | public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion) |
||
371 | |||
372 | /** |
||
373 | * @Given /^([^"]+) gives(?:| another) ("[^"]+%") off every product (classified as "[^"]+")$/ |
||
374 | */ |
||
375 | public function itGivesPercentageOffEveryProductClassifiedAs( |
||
382 | |||
383 | /** |
||
384 | * @Given /^([^"]+) gives(?:| another) ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/ |
||
385 | */ |
||
386 | public function itGivesFixedOffEveryProductClassifiedAs( |
||
393 | |||
394 | /** |
||
395 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/ |
||
396 | */ |
||
397 | public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt( |
||
404 | |||
405 | /** |
||
406 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/ |
||
407 | */ |
||
408 | public function thisPromotionGivesOffOnEveryProductPricedBetween( |
||
420 | |||
421 | /** |
||
422 | * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/ |
||
423 | */ |
||
424 | public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt( |
||
431 | |||
432 | /** |
||
433 | * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/ |
||
434 | */ |
||
435 | public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween( |
||
447 | |||
448 | /** |
||
449 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/ |
||
450 | */ |
||
451 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs( |
||
460 | |||
461 | /** |
||
462 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/ |
||
463 | */ |
||
464 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr( |
||
473 | |||
474 | /** |
||
475 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/ |
||
476 | */ |
||
477 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt( |
||
488 | |||
489 | /** |
||
490 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/ |
||
491 | */ |
||
492 | public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth) |
||
498 | |||
499 | /** |
||
500 | * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/ |
||
501 | */ |
||
502 | public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth) |
||
508 | |||
509 | /** |
||
510 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/ |
||
511 | */ |
||
512 | public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder( |
||
521 | |||
522 | /** |
||
523 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/ |
||
524 | */ |
||
525 | public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast( |
||
539 | |||
540 | /** |
||
541 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/ |
||
542 | */ |
||
543 | public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast( |
||
563 | |||
564 | /** |
||
565 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/ |
||
566 | */ |
||
567 | public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr( |
||
585 | |||
586 | /** |
||
587 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/ |
||
588 | */ |
||
589 | public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs( |
||
604 | |||
605 | /** |
||
606 | * @Given /^(it) is coupon based promotion$/ |
||
607 | */ |
||
608 | public function itIsCouponBasedPromotion(PromotionInterface $promotion) |
||
614 | |||
615 | /** |
||
616 | * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/ |
||
617 | */ |
||
618 | public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel) |
||
624 | |||
625 | /** |
||
626 | * @Given /^the (coupon "[^"]+") was used up to its usage limit$/ |
||
627 | */ |
||
628 | public function theCouponWasUsed(PromotionCouponInterface $coupon) |
||
634 | |||
635 | /** |
||
636 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/ |
||
637 | */ |
||
638 | public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
644 | |||
645 | /** |
||
646 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/ |
||
647 | */ |
||
648 | public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
652 | |||
653 | /** |
||
654 | * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/ |
||
655 | */ |
||
656 | public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
660 | |||
661 | /** |
||
662 | * @Given /^([^"]+) gives ("[^"]+%") off the order for customers from ("[^"]*" group)$/ |
||
663 | */ |
||
664 | public function thePromotionGivesOffTheOrderForCustomersFromGroup( |
||
675 | |||
676 | /** |
||
677 | * @param array $taxonCodes |
||
678 | * |
||
679 | * @return array |
||
680 | */ |
||
681 | private function getTaxonFilterConfiguration(array $taxonCodes) |
||
685 | |||
686 | /** |
||
687 | * @param array $productCodes |
||
688 | * |
||
689 | * @return array |
||
690 | */ |
||
691 | private function getProductsFilterConfiguration(array $productCodes) |
||
695 | |||
696 | /** |
||
697 | * @param int $minAmount |
||
698 | * @param int $maxAmount |
||
699 | * |
||
700 | * @return array |
||
701 | */ |
||
702 | private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null) |
||
711 | |||
712 | /** |
||
713 | * @param PromotionInterface $promotion |
||
714 | * @param int $discount |
||
715 | * @param array $configuration |
||
716 | * @param PromotionRuleInterface|null $rule |
||
717 | */ |
||
718 | private function createUnitFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null) |
||
729 | |||
730 | /** |
||
731 | * @param PromotionInterface $promotion |
||
732 | * @param int $discount |
||
733 | * @param array $configuration |
||
734 | * @param PromotionRuleInterface|null $rule |
||
735 | */ |
||
736 | private function createUnitPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null) |
||
747 | |||
748 | /** |
||
749 | * @param PromotionInterface $promotion |
||
750 | * @param int $discount |
||
751 | * @param array $configuration |
||
752 | * @param PromotionRuleInterface|null $rule |
||
753 | * @param ChannelInterface|null $channel |
||
754 | */ |
||
755 | private function createFixedPromotion( |
||
766 | |||
767 | /** |
||
768 | * @param PromotionInterface $promotion |
||
769 | * @param float $discount |
||
770 | * @param array $configuration |
||
771 | * @param PromotionRuleInterface $rule |
||
772 | */ |
||
773 | private function createPercentagePromotion( |
||
781 | |||
782 | /** |
||
783 | * @param PromotionInterface $promotion |
||
784 | * @param PromotionActionInterface $action |
||
785 | * @param array $configuration |
||
786 | * @param PromotionRuleInterface|null $rule |
||
787 | */ |
||
788 | private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null) |
||
800 | } |
||
801 |
Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.