A bloated class is a class with too many responsibilities. Every system change seems to require a change to this class.
A bloated class often has many special cases: attributes or behavior valid for some instances but not others.
Often programmers attempt to deal with special cases by introducing type tags.
Another way to deal with special cases is by introducing multi-way conditionals.
Bloated classes often contain bloated methods.
Extract Class
Extract Subclass
Replace Data Value with Object
Duplicated code can be the result of too many copy and paste jobs.
Extract Method
Extract Class
Pull Up method
Class A knows too much about the private details of class B. A knows which classes B delegates to, A can access the private and protected members of B, and A spends most of its time invoking the getters and setters of B (feature envy).
Move Method
Replace Bi-directional Association with Unidirectional
Replace Inheritance with Delegation
Hide Delegation
A library class that we can't modify doesn't have all of the features we wish it had.
Introduce Foreign Method
Introduce Local Extension
A lazy class doesn't have enough responsibilities. A lazy class may sometimes be the result of speculative generality.
Inline Class
Collapse Hierarchy
Long methods are difficult to understand and maintain. As a rule of thumb, anything over half a page is too long. Another rule of thumb: instead of inserting a comment to explain a task within a long method, thing about extracting the task into a well-named method. Ideally, methods should be so short and so well-named, that reading the code isn't even necessary.
Extract Method
A middleman forwards requests from the client to a delegate object. Generally, the middleman serves a purpose. It translates the request into the language of the delegate, it sends the request over a machine boundary, it handles some requests by itself, it manages memory on behalf of the delegate, etc. In some cases, however, the middleman looses its purpose and only seems to stand in the way between the client and the delegate.
Remove Middle Man
Inline Method
Replace Delegation with Inheritance
It's okay for subclass B to override some of the methods it inherits from superclass A, but taken to the extreme, one begins to wonder if B should be a subclass of A.
Replace Inheritance with Delegation
The purpose of design is to try to anticipate future requirements. Taken to an extreme, this can result in the Biped superclass of Employee, the planet field of Address, or the "jump to hyperspace" method of Airplane.
Collapse Hierarchy
Inline Class
Just as the goto statement became the bad boy of Structured Programming, the switch statement has become the bad boy of Object-Oriented Programming. Object-Oriented Programming is about data-driven control. Programmer's shouldn't be in the business of specifying the flow of control. Instead, programmers should be in the business of specifying data. The data should decide the flow of control. This is the purpose of overloading, subsumption, and dynamic dispatch.
Replace Conditional with Polymorphism
Replace Type Tags with Subclasses