software to make it easier to understand and cheaper to modify without changing its observable behavior. Refactoring (noun) It’s also a common error to see refactoring as something to fix past mistakes or clean up ugly code.
not undergo any changes are untrue most of the time. As people change code to achieve short-term goals, often without a full comprehension of the architecture, the code loses its structure. Loss of structure has a cumulative effect. You will find yourself refactoring ugly code, but good code also needs refactoring.
confusing. Primitive Obsession Primitive types, such as integers, floating pointing numbers and strings, don’t represent a type of data we are dealing with.
looking at a block of code trying to figure out what it’s doing then you should extract it into a function. Inline Function Inverse of Extract Function, where a function has a body as clear as the name.
is too big to easily understand, you need to consider where it can be split. Inline Class When a class is no longer pulling its weight and shouldn’t be around anymore.
name allows you to understand what the function does when you see it called. Rename Variable Naming things well is at the heart of a clear programming. Rename Fields Fields names are important especially when they are widely used across an application.
often together could be replaced by a data structure. Replace Primitive with Object e.g. Phone number, money Preserve Whole Object Values from the same object passed as an argument can be replaced by passing the whole object.
branches of the conditional. abstract class Bird { // ... abstract function getSpeed(); // ... } class European extends Bird { public function getSpeed() { return $this->getBaseSpeed(); } } class African extends Bird { public function getSpeed() { return $this->getBaseSpeed() - $this->getLoadFactor() * $this->numberOfCoconuts; } } class NorwegianBlue extends Bird { public function getSpeed() { return ($this->isNailed) ? 0 : $this->getBaseSpeed($this->voltage); } } // Somewhere in Client code. $speed = $bird->getSpeed(); class Bird { // ... public function getSpeed() { switch ($this->type) { case EUROPEAN: return $this->getBaseSpeed(); case AFRICAN: return $this->getBaseSpeed() - $this->getLoadFactor() * $this->numberOfCoconuts; case NORWEGIAN_BLUE: return ($this->isNailed) ? 0 : $this->getBaseSpeed($this->voltage); } throw new Exception("Should be unreachable"); } // ... }
that provides special behavior for particular cases. if ($customer === null) { $plan = BillingPlan::basic(); } else { $plan = $customer->getPlan(); } class NullCustomer extends Customer { public function isNull() { return true; } public function getPlan() { return new NullPlan(); } // Some other NULL functionality. } // Replace null values with Null-object. $customer = ($order->customer !== null) ? $order->customer : new NullCustomer; // Use Null-object as if it's normal subclass. $plan = $customer->getPlan();
single point where the class is instantiated you avoid tight coupling. class Employee { // ... public function __construct($type) { $this->type = $type; } // ... } class Employee { // ... static public function create($type) { $employee = new Employee($type); // do some heavy lifting. return $employee; } // ... }