module 3. smells between classes course: refactoring

Post on 17-Jan-2016

217 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Module 3. Smells Between Classes

Course: Refactoring

Overview: Smells Between Classes

Data

Inheritance

Responsibility

Accommodating Change

Library Classes

Lesson: Data

Primitive Obsession

Data Class

Data Clump

Temporary Field

Primitive Obsession

Symptoms Uses of the primitive or near-primitive types (int, float, String, etc.) Constants and enumerations representing small integers String constants representing field names

Causes Missing class Simulated types Simulated field accessors

What to Do Replace Data Value with Object

Replace Type Code with Class; Replace Type Code with Subclass; Replace Type Code with State/Strategy; Replace Conditional with Polymorphism

Replace Array with Object

Payoff Improves communication.

Data Class

Symptoms

class consists only of public data members

depend on the mutability and representation of the class

Causes

realize that some data is part of an independent object

What to Do

Encapsulate Field

Remove Setting Methods

Encapsulate Collection

Look at each client of the object.

Payoff

Improves communication.

Data Clump

Symptoms the same items frequently appear together in classes and parameter

lists. there are groups of fields and methods together within the class groups of field names start or end with similar substrings.

Causes The items are typically part of some other entity

What to Do Extract Class. Introduce Parameter Object Preserve Whole Object Move Method, etc

Payoff Improves communication. May expose duplication. Usually reduces

size.

Temporary Field

Symptoms

A field is set only at certain times, and it is null (or unused) at other times.

Causes

an algorithm that passes around information through the fields

What to Do

Extract Class

Payoff

Improves communication and clarity.

Exercise:

• Alternative Representations• Proper Names (Challenging)

Lesson: Inheritance

Refused Bequest

Inappropriate Intimacy (Subclass Form)

Lazy Class

See also these other smells related to inheritance:

Simulated Inheritance (Switch Statement) Parallel Inheritance Hierarchies Combinatorial Explosion

Refused Bequest

Symptoms honest refusal implicit refusal through a handle to the subclasses. Inheritance doesn't really make sense

Causes a class may inherit without really intending the class to be

substitutable a conscious decision to let subclasses deny use of some

features

What to Do you might decide to leave it as is. Replace Inheritance with Delegation. Extract Subclass, Push Down Field, and Push Down Method

Inappropriate Intimacy (Subclass Form)

Symptoms

A class accesses internal (should-be-private) parts of its parent.

Causes

Parent and child classes be more coupled together

What to Do

Self Encapsulate Field.

Form Template Method.

Replace Inheritance with Delegation.

Payoff

Reduces duplication.

Often improves communication.

May reduce size.

Lazy Class

Symptoms

A class isn't doing.

Causes

all responsibilities have been moved to other places

What to Do

Collapse Hierarchy.

Inline Class.

Payoff

Reduces size. Improves communication. Improves simplicity.

Exercise:

Collection classes

Real application

Lesson: Responsibility

Feature Envy

Inappropriate Intimacy (General Form)

Message Chains

Middle Man

Feature Envy

Symptoms

A method seems to be focused on manipulating the data of other classes rather than its own.

Causes

This is very common among clients of current and former data classes, but you can see it for any class and its clients.

What to Do

Move Method

Extract Method

Inappropriate Intimacy (General Form)

Symptoms One class accesses internal (should-be-private) parts of another

class

Causes The two classes probably became intertwined a little at a time. There may be a missing class that should mediate between them.

What to Do Move Method and Move Field Extract Class and Hide Delegate Change Bidirectional Reference to Unidirectional If a subclass is too coupled to its parent

Self Encapsulate Field.

Form Template Method.

Replace Inheritance with Delegation.

Message Chains

Symptoms

You see calls of the form:a.b().c().d()

Causes

the problem is that this couples both the objects and the path to get to them.

What to Do

Extract Method and Move Method

Use Hide Delegate

Middle Man

Symptoms object:f()

{ delegate.f(); }

Causes result from applying Hide Delegate to address

Message Chains

What to Do Remove Middle Man Replace Delegation with Inheritance.

Payoff Reduces size.

Exercise:

Middle Man

Account Cart

Exercise: Hide delegate

Lesson: Accommodating Change

Divergent Change

Shotgun Surgery

Parallel Inheritance Hierarchies

Combinatorial Explosion

Divergent Change

Symptoms

You find yourself changing the same class for different reasons.

Causes

The class picks up more responsibilities as it evolves

What to Do

Extract Class

Extract Superclass or Extract Subclass

Shotgun Surgery

Symptoms

Simple change requires to change several classes.

Causes

One responsibility is split among several classes.

Elimination Divergent Change.

What to Do

Extract Class

Move Field and Move Method.

Parallel Inheritance Hierarchies

Symptoms

required subclass in another hierarchy.

subclasses have the same prefix

a special case of Shotgun Surgery

Causes

The hierarchies probably grew in parallel, a class and its pair being needed at the same time.

What to Do

Move Field and Move Method

Payoff

Reduces duplication. May improve communication. May reduce size.

Combinatorial Explosion

Symptoms

you have to introduce multiple classes at various points of the hierarchy.

you notice that each layer of the hierarchy uses a common set of words

Causes

independent decisions instead get implemented via a hierarchy.

What to Do

Replace Inheritance with Delegation

Tease Apart Inheritance

Exercise:

Divergent Changes (csv writer)

Shotgun Surgery

Documents

Exercise: Shotgun Surgery

In code you have access to, find examples of this problem. Some frequent candidates:

Configuration information. Logging. Persistence. Sometimes it takes two calls on an object

to get something common done, and this two-step process is used in several places.

Lesson: Library Classes

Incomplete Library Class

Incomplete Library Class

Symptoms

library has no some features

Causes

the author of the library class didn't anticipate your need

What to Do

contact owner

Introduce Foreign Method

Introduce Local Extension

introduce a layer covering the library

Exercise:

Exercise:

Redraw this as a UML package diagram showing dependencies.

Explain how the bulk of your code does or does not depend on the library code in each of these situations.

What effects does this layering have in terms of:

Conceptual integrity?

Portability?

Performance?

Testing?

Exercise:

Review

Data

Inheritance

Responsibility

Accommodating Change

Library Classes

Gen-A-Refactoring

(—) in combinations that don't make sense,

(+) in those that are in Fowler's Refactoring catalog

(*) in those that make sense but aren't in the catalog.

top related