Smell Detail

Data Clumps

数据泥团

Bloaters

The same group of data items always appears together in multiple places.

Define

Introduction

When you see the same set of data items (typically 2–3 fields) duplicated across multiple classes, that data should be extracted into its own class.

Key Identifiers

  • The same combination of fields is repeated in multiple classes
  • These fields are always passed or used together
  • The same parameter grouping frequently appears in method parameter lists
  • A proper abstraction concept is missing

Refactoring Suggestions

  1. Extract Class: Create a dedicated class for the data clump
  2. Introduce Parameter Object: Replace long parameter lists with an object
  3. Keep Data Cohesive: Keep related data together to preserve integrity

Explanation

startX, startY and endX, endY often appear together. A Point (or perhaps a Range/LineSegment depending on context) class should be introduced to encapsulate the coordinate concept and improve readability and maintainability.

Code Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Rectangle {
private int startX, startY;
private int endX, endY;
public void draw(int startX, int startY, int endX, int endY) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
}
public int getArea() {
return Math.abs((endX - startX) * (endY - startY));
}
}
class Circle {
private int centerX, centerY;
private int radius;
public void draw(int centerX, int centerY, int radius) {
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
class Line {
private int startX, startY;
private int endX, endY;
public void draw(int startX, int startY, int endX, int endY) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
}
public double getLength() {
return Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
}
}