Code smells

Duration

Description

30m

Introduction to code smells

Introduction to code smells

Design smells

Rigidity

  • Tendency of software to be difficult to change

  • The system is hard to change because every change forces many other changes to other parts of the system.

  • Changes propagate via dependencies to other modules.

Fragility

  • Tendency of software to break in many places when a single change is made.

  • Design is easy to break, changes cause the system to break in places that have no conceptual relationship to the part that was changed.

  • Changes cause cascading effects to many places

  • The code breaks in unexpected places that have no conceptual relationship with the changed area

  • Fixing the problems causes new problems

Immobility

  • It is hard to disentangle the system into components that can be reused in the other systems.

  • Thee code is so tangled that it is the code is so tangled that it is impossible to reuse anything impossible to reuse anything.

Viscosity

  • Viscosity of the software

    • Doing things right is harder than doing things wrong.

  • Viscosity of the environment

    • When a change is needed, you are tempted to hack rather than to preserve the original design.

    • You are reluctant to execute a fast feedback loop and instead tend to code larger pieces

Needless complexity

  • The design contains infrastructure that adds no direct benefit.

    • Too much anticipation of future needs

    • YAGNI

Needless repetition

  • The design contains repeating structures that could be unified under a single abstraction.

  • Bugs found in a repeating unit have to bugs found in a repeating unit have to be fixed in every repetition.

Opacity

  • Tendency of a module to be difficult to understand

  • It is hard to read and understand. It does not express its intent well.

  • A constant effort is needed to keep the code readable

Categories

Bloaters

Bloaters are code, methods and classes that have increased to such gargantuan proportions that they are hard to work with. Usually these smells do not crop up right away, rather they accumulate over time as the program evolves (and especially when nobody makes an effort to eradicate them).

Code smell

Description

Long method

Methods should do only one thing

SRP violation

One level of abstraction

No more than 5 to 15 lines

Long parameter list

Ideal - 0 parameters (niladic) Ok - 1 parameter (monadic) Acceptable - 2 parameters (dyadic) Debatable (avoid) - 3 parameters (triadic) Special justification - 4+ parameters (polyadic)

Primitive obsession

Don't use primitive types as substitutes for classes.

If the data type is sufficiently complex, use a class to represent it.

Large class

Classes should have only one responsibility. No more than 50 lines per class.

Data clumps

Same data items together in lots of places.

Special case of duplicated code.

DRY violation.

Object-orientation abusers

All these smells are incomplete or incorrect application of object-oriented programming principles.

Code smell

Description

Switch statement

Often found as a poor workaround for polymorphism.

Can lead to the same switch statement scattered about a program in different places.

Temporary field

A class contains an instance variable set only in certain circumstances.

Alternative classes with different interfaces

If two classes are similar on the inside but different on the outside, perhaps they can be modified to share a common interface.

Refused bequest

Usually noticeable where a not implemented exception is thrown in a method implementation from a superclass or interface.

Usually means the hierarchy is wrong.

Change preventers

These smells mean that if you need to change something in one place in your code, you have to make many changes in other places too. Program development becomes much more complicated and expensive as a result.

Code smell

Description

Divergent change

One class is commonly changed in different ways for different reasons.

Shotgun surgery

One change forces lots of little changes in different classes.

Opposite of divergent change.

Parallel inheritance hierarchies

A special case of shotgun surgery.

Creating a subclass of one class, forces subclass of another.

Dispensables

A dispensable is something pointless and unneeded whose absence would make the code cleaner, more efficient and easier to understand.

Code smell

Description

Lazy class

A class that does too little.

Maybe acting only as a middle man, or data class.

Can be caused by speculative generality.

Data class

Classes that have fields, properties, and nothing else.

Anaemic classes that contain no behaviour.

Special case of lazy class.

Duplicated code

Identical or very similar code exists in more than one location.

Duplicated knowledge.

Dead code

Code that has no references to it, commented code.

Speculative generality

Only users of method or class are test cases.

Any YAGNI violation.

Commented code

Often added to explain poorly written code.

Often not updated when code changes, becoming increasingly misleading. Make effort to create code that expresses intent instead of comments.

Couplers

All the smells in this group contribute to excessive coupling between classes or show what happens if coupling is replaced by excessive delegation.

Code smell

Description

Feature envy

A class that uses the methods or properties of of another class excessively.

Inappropriate intimacy

A class that has dependencies on implementation details of another class. A special case of feature envy.

Message Chains

Too many dots. e.g Dog.Body.Tail.Wag() should be Dog.ExpressHappiness()

Middle Man

A class that delegates most or all of its work without adding any value as a co-ordinator or orchestrator. Beware classes that are wrappers over other classes or existing functionality. A special case of lazy class.

Use TDD Habits in the appendices for this exercise

NEW HABIT - Use code smell to detect problems and refactor your design accordingly

Last updated