Complex classes like LaraCart 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 LaraCart, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | class LaraCart implements LaraCartContract |
||
| 14 | { |
||
| 15 | const SERVICE = 'laracart'; |
||
| 16 | const QTY = 'qty'; |
||
| 17 | const PRICE = 'price'; |
||
| 18 | const HASH = 'generateCartHash'; |
||
| 19 | const RANHASH = 'generateRandomCartItemHash'; |
||
| 20 | |||
| 21 | public $cart; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * LaraCart constructor. |
||
| 25 | */ |
||
| 26 | public function __construct() |
||
| 30 | |||
| 31 | /** |
||
| 32 | * Sets and Gets the instance of the cart in the session we should be using |
||
| 33 | * |
||
| 34 | * @param string $instance |
||
| 35 | * |
||
| 36 | * @return LaraCart |
||
| 37 | */ |
||
| 38 | public function setInstance($instance = 'default') |
||
| 48 | |||
| 49 | /** |
||
| 50 | * Gets the instance in the session |
||
| 51 | * |
||
| 52 | * @param string $instance |
||
| 53 | * |
||
| 54 | * @return $this cart instance |
||
| 55 | */ |
||
| 56 | public function get($instance = 'default') |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Updates cart session |
||
| 67 | */ |
||
| 68 | public function update() |
||
| 74 | |||
| 75 | /** |
||
| 76 | * |
||
| 77 | * Formats the number into a money format based on the locale and international formats |
||
| 78 | * |
||
| 79 | * @param $number |
||
| 80 | * @param $locale |
||
| 81 | * @param $internationalFormat |
||
| 82 | * @param $format |
||
| 83 | * |
||
| 84 | * @return string |
||
| 85 | */ |
||
| 86 | public function formatMoney($number, $locale = null, $internationalFormat = null, $format = true) |
||
| 100 | |||
| 101 | /** |
||
| 102 | * Gets an an attribute from the cart |
||
| 103 | * |
||
| 104 | * @param $attribute |
||
| 105 | * @param $defaultValue |
||
| 106 | * |
||
| 107 | * @return mixed |
||
| 108 | */ |
||
| 109 | public function getAttribute($attribute, $defaultValue = null) |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Gets all the carts attributes |
||
| 116 | * |
||
| 117 | * @return mixed |
||
| 118 | */ |
||
| 119 | public function getAttributes() |
||
| 123 | |||
| 124 | /** |
||
| 125 | * Adds an Attribute to the cart |
||
| 126 | * |
||
| 127 | * @param $attribute |
||
| 128 | * @param $value |
||
| 129 | */ |
||
| 130 | public function setAttribute($attribute, $value) |
||
| 136 | |||
| 137 | /** |
||
| 138 | * Removes an attribute from the cart |
||
| 139 | * |
||
| 140 | * @param $attribute |
||
| 141 | */ |
||
| 142 | public function removeAttribute($attribute) |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Finds a cartItem based on the itemHash |
||
| 151 | * |
||
| 152 | * @param $itemHash |
||
| 153 | * |
||
| 154 | * @return CartItem | null |
||
| 155 | */ |
||
| 156 | public function getItem($itemHash) |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Gets all the items within the cart |
||
| 163 | * |
||
| 164 | * @return array |
||
| 165 | */ |
||
| 166 | public function getItems() |
||
| 177 | |||
| 178 | /** |
||
| 179 | * Creates a CartItem and then adds it to cart |
||
| 180 | * |
||
| 181 | * @param $itemID |
||
| 182 | * @param null $name |
||
| 183 | * @param int $qty |
||
| 184 | * @param string $price |
||
| 185 | * @param array $options |
||
| 186 | * @param bool|false $taxable |
||
| 187 | * @param bool|false $lineItem |
||
| 188 | * |
||
| 189 | * @return CartItem |
||
| 190 | */ |
||
| 191 | public function add( |
||
| 212 | |||
| 213 | /** |
||
| 214 | * Creates a CartItem and then adds it to cart |
||
| 215 | * |
||
| 216 | * @param string|int $itemID |
||
| 217 | * @param null $name |
||
| 218 | * @param int $qty |
||
| 219 | * @param string $price |
||
| 220 | * @param array $options |
||
| 221 | * |
||
| 222 | * @return CartItem |
||
| 223 | */ |
||
| 224 | public function addLine($itemID, $name = null, $qty = 1, $price = '0.00', $options = [], $taxable = true) |
||
| 228 | |||
| 229 | /** |
||
| 230 | * Adds the cartItem into the cart session |
||
| 231 | * |
||
| 232 | * @param CartItem $cartItem |
||
| 233 | * |
||
| 234 | * @return CartItem |
||
| 235 | */ |
||
| 236 | public function addItem(CartItem $cartItem) |
||
| 251 | |||
| 252 | /** |
||
| 253 | * Updates an items attributes |
||
| 254 | * |
||
| 255 | * @param $itemHash |
||
| 256 | * @param $key |
||
| 257 | * @param $value |
||
| 258 | * |
||
| 259 | * @return CartItem |
||
| 260 | * |
||
| 261 | * @throws Exceptions\InvalidPrice |
||
| 262 | * @throws Exceptions\InvalidQuantity |
||
| 263 | */ |
||
| 264 | public function updateItem($itemHash, $key, $value) |
||
| 282 | |||
| 283 | /** |
||
| 284 | * Removes a CartItem based on the itemHash |
||
| 285 | * |
||
| 286 | * @param $itemHash |
||
| 287 | */ |
||
| 288 | public function removeItem($itemHash) |
||
| 299 | |||
| 300 | /** |
||
| 301 | * Get the count based on qty, or number of unique items |
||
| 302 | * |
||
| 303 | * @param bool $withItemQty |
||
| 304 | * |
||
| 305 | * @return int |
||
| 306 | */ |
||
| 307 | public function count($withItemQty = true) |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Empties the carts items |
||
| 323 | */ |
||
| 324 | public function emptyCart() |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Completely destroys cart and anything associated with it |
||
| 335 | */ |
||
| 336 | public function destroyCart() |
||
| 344 | |||
| 345 | /** |
||
| 346 | * Gets the coupons for the current cart |
||
| 347 | * |
||
| 348 | * @return array |
||
| 349 | */ |
||
| 350 | public function getCoupons() |
||
| 354 | |||
| 355 | /** |
||
| 356 | * // TODO - badly named |
||
| 357 | * Finds a specific coupon in the cart |
||
| 358 | * |
||
| 359 | * @param $code |
||
| 360 | * @return mixed |
||
| 361 | */ |
||
| 362 | public function findCoupon($code) |
||
| 366 | |||
| 367 | /** |
||
| 368 | * // todo - badly named |
||
| 369 | * Applies a coupon to the cart |
||
| 370 | * |
||
| 371 | * @param CouponContract $coupon |
||
| 372 | */ |
||
| 373 | public function addCoupon(CouponContract $coupon) |
||
| 383 | |||
| 384 | /** |
||
| 385 | * Removes a coupon in the cart |
||
| 386 | * |
||
| 387 | * @param $code |
||
| 388 | */ |
||
| 389 | public function removeCoupon($code) |
||
| 403 | |||
| 404 | /** |
||
| 405 | * Gets a speific fee from the fees array |
||
| 406 | * |
||
| 407 | * @param $name |
||
| 408 | * |
||
| 409 | * @return mixed |
||
| 410 | */ |
||
| 411 | public function getFee($name) |
||
| 415 | |||
| 416 | /** |
||
| 417 | * Getes all the fees on the cart object |
||
| 418 | * |
||
| 419 | * @return mixed |
||
| 420 | */ |
||
| 421 | public function getFees() |
||
| 425 | |||
| 426 | /** |
||
| 427 | * Allows to charge for additional fees that may or may not be taxable |
||
| 428 | * ex - service fee , delivery fee, tips |
||
| 429 | * |
||
| 430 | * @param $name |
||
| 431 | * @param $amount |
||
| 432 | * @param bool|false $taxable |
||
| 433 | * @param array $options |
||
| 434 | */ |
||
| 435 | public function addFee($name, $amount, $taxable = false, Array $options = []) |
||
| 441 | |||
| 442 | /** |
||
| 443 | * Reemoves a fee from the fee array |
||
| 444 | * |
||
| 445 | * @param $name |
||
| 446 | */ |
||
| 447 | public function removeFee($name) |
||
| 453 | |||
| 454 | /** |
||
| 455 | * Gets all the fee totals |
||
| 456 | * |
||
| 457 | * @param boolean $format |
||
| 458 | * |
||
| 459 | * @return string |
||
| 460 | */ |
||
| 461 | public function feeTotals($format = true) |
||
| 474 | |||
| 475 | /** |
||
| 476 | * Gets the total amount discounted |
||
| 477 | * |
||
| 478 | * @param bool|true $format |
||
| 479 | * |
||
| 480 | * @return int|string |
||
| 481 | */ |
||
| 482 | public function totalDiscount($format = true) |
||
| 492 | |||
| 493 | |||
| 494 | /** |
||
| 495 | * Gets the total tax for the cart |
||
| 496 | * |
||
| 497 | * @param bool|true $format |
||
| 498 | * |
||
| 499 | * @return string |
||
| 500 | */ |
||
| 501 | public function taxTotal($format = true) |
||
| 508 | |||
| 509 | /** |
||
| 510 | * Gets the subtotal of the cart with or without tax |
||
| 511 | * |
||
| 512 | * @param bool|false $tax |
||
| 513 | * @param boolean $format |
||
| 514 | * @param boolean $withDiscount |
||
| 515 | * |
||
| 516 | * @return string |
||
| 517 | */ |
||
| 518 | public function subTotal($tax = false, $format = true, $withDiscount = true) |
||
| 529 | |||
| 530 | /** |
||
| 531 | * Gets the total of the cart with or without tax |
||
| 532 | * |
||
| 533 | * @param boolean $format |
||
| 534 | * @param boolean $withDiscount |
||
| 535 | * |
||
| 536 | * @return string |
||
| 537 | */ |
||
| 538 | public function total($format = true, $withDiscount = true) |
||
| 548 | } |
||
| 549 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.