By: Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts
Decomposing and redistributing methods:
– locate modified local variables, if there is only one, extract it to a separate method and return it.
– A method should be on the object whose data it uses. E.g: “amount calculation only uses information of the Rental, methods should not be under Customer but under Rental”
– local/temp/auxiliar variables are often a problem in that they cause a lot of parameters to be passed around when they don’t have to be. Easily lose track of what they are there for.
– Get rid of local variables that are assigned as result of an extracted/refactored method. Performance might be affected, but that is another step outside the refactoring process. Optimisation is much easier done with a refactored code.
– Replace temp/local variables with “Query”-> replace with private helper methods (which could end up being public easily)
– Replace conditional logic with Polymorphism. “It is a bad idea to do a switch based on an attribute of another object. If you must use a switch statement, it should be on your own data, not on someone else’s”
– If inheritance is not an option, you need the object to change class during its lifetime (New Release Movie can change to Regular Movie during the lifetime) -> Strategy or State pattern.
– Strategy or State pattern a very similar, to differentiate them ask question: Does the class represent an algorithm for calculating or does it represent a state?.
enables an algorithm’s behavior to be selected at runtime
– defines a family of algorithms,
– encapsulates each algorithm, and
– makes the algorithms interchangeable within that family.
For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed.