Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tips for daily refactoring

Tips for daily refactoring

Tidy up your code every day a bit

Fran Iglesias

November 05, 2018
Tweet

More Decks by Fran Iglesias

Other Decks in Programming

Transcript

  1. Tidy code every time you work with it… Little changes

    One or two per commit Better on tested code, or… Perform secure refactors
  2. …and overall code quality will increase without effort Every little

    change contributes The more we work in a piece of code, the better it becomes Pave the way for deeper refactoring
  3. Tidy up the code every day to Remove garbage Reflect

    the evolving knowledge about the system Improve the life of future devs 
 (probably you)
  4. Before After Remove garbage public function calculateFee( $data, $period )

    { $fee = $this->calculate($data); if ($period === ‘monthly’) { $fee = $fee / 12; } } Redundant comment: for what? Commented comment: what does this do here? Todo: What was the original intention? // Calculates the fee public function calculateFee( $data, $period ) { // $data = $this->clean($data); $fee = $this->calculate($data); /** @todo: refactor this */ if ($period === ‘monthly’) { $fee = $fee / 12; } }
  5. Better names Change the name of a variable, constant, method,

    class, etc, to: • Better reflect a concept or intent • Update its meaning
  6. Better names public function calculateFee( $data, $period ) { $fee

    = $this->calculate($data); if ($period === ‘monthly’) { $fee = $fee / 12; } } public function calculateFee( $data, $periodicity ) { $fee = $this->calculate($data); if ($periodicity === ‘monthly’) { $fee = $fee / 12; } } Before After $period not longer means “period” here. Perhaps long time ago it meant that, but now clearly refers to another concept. This gap carries a cognitive load we don’t need.
  7. Tidy up conditionals Good conditionals should: • Reveal the simplest

    case • Return early: guard clauses • Ternary operator if applicable • Avoid the negation whenever possible
  8. Before After Reveal the simplest case The simplest case could

    be concealed by the more complex one. if ($someCondition) { // Lots // and // lots // of // lines // .. } else { // one line } if (!$someCondition) { // one line } else { // Lots // and // lots // of // lines // .. }
  9. Before After Guard clauses public function calculateFee($data, $period) { if

    (!$data) { throw new Exception(‘Bad data’); } $fee = $this->calculate($data); if ($period === ‘monthly’) { $fee = $fee / 12; } } Return or fail early and reduce the complexity of the function. public function calculateFee($data, $period) { if ($data) { $fee = $this->calculate($data); if ($period === ‘monthly’) { $fee = $fee / 12; } } else { throw new Exception(‘Bad data’); } }
  10. Before After Ternary operator Use ternary operator when there are

    two ways to perform a calculation. public function total() { $cost = $this->shipping->isPriority ? $this->shipping->zone() * self::PRIORITY : $this->shipping->zone() * self::STANDARD; } public function total() { if ($this->shipping->isPriority()) { $cost = $this->shipping->zone() * self::PRIORITY; } else { $cost = $this->shipping->zone() * self::STANDARD; } }
  11. Redundancy $commission = $this->commissionRepository->lastByCups($reactivationDTO->cups()); if (null === $commission) { throw

    new CommissionDoesNotExistException( sprintf(self::MISSING_CUPS, $reactivationDTO->cups()) ); } $commission = $this->commissionRepository->lastByCups($reactivationDTO->cups()); if (!$commission) { throw new CommissionDoesNotExistException( sprintf(self::MISSING_CUPS, $reactivationDTO->cups()) ); } Before After Also to note: what about throw exception from inside repository call? $commission = $this->commissionRepository->lastByCups($reactivationDTO->cups()); After all
  12. Before After Parts of expressions to variables $discount = $price

    * $pct / 100; $amount = $price - $discount; Extract parts to create self- explanatory expressions $amount = $price - ($price * $pct / 100);
  13. Before After Conditions to meaningful methods if ($this->userCanModifyProduct() { //

    do Something } function userCanModifyProduct() { return $user->hasModifyPrivilege() && $user- >isAuthorized() && $product->isAvailable(); } Extract complex conditional to make them self-explanatory if ($user->hasModifyPrivilege() && $user->isAuthorized() && $product- >isAvailable()) { // do Something }
  14. Before After Legs of conditionals to methods if ($someCondition) {

    $this->doThis() } else { $this->doAnotherThings() } Moving the legs of conditionals to their own methods makes easy to understand the main flow of the code, hiding concrete details. if ($someCondition) { // Lots // and // lots // of // lines // .. } else { // Lots // and // lots // of // lines // … }
  15. Reorder code Coherent declarations and initializations Define a sort criteria…

    • Constants • Fields • Public methods first • Public methods first with their extracted private methods next to them…