Anti Patterns

Bloated Class

Problem

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.

Refactorings

Extract Class

Extract Subclass

Replace Data Value with Object

Duplicated Code

Problem

Duplicated code can be the result of too many copy and paste jobs.

Refactorings

Extract Method

Extract Class

Pull Up method

Inappropriate Intimacy

Problem

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).

Refactorings

Move Method

Replace Bi-directional Association with Unidirectional

Replace Inheritance with Delegation

Hide Delegation

Incomplete Library Class

Problem

A library class that we can't modify doesn't have all of the features we wish it had.

Refactorings

Introduce Foreign Method

Introduce Local Extension

Lazy Class

Problem

A lazy class doesn't have enough responsibilities. A lazy class may sometimes be the result of speculative generality.

Refactorings

Inline Class

Collapse Hierarchy

Long Method

Problem

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.

Refactorings

Extract Method

Middle Man

Problem

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.

Refactorings

Remove Middle Man

Inline Method

Replace Delegation with Inheritance

Refused Bequest

Problem

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.

Refactorings

Replace Inheritance with Delegation

Speculative Generality

Problem

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.

Refactorings

Collapse Hierarchy

Inline Class

Switch Statements

Problem

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.

Refactorings

Replace Conditional with Polymorphism

Replace Type Tags with Subclasses