Smell Detail

Long Parameter List

过长参数列表

Bloaters

A function has too many parameters, making it hard to understand and use.

Define

Introduction

When a function has too many parameters, it becomes harder to understand and use. Typically, once a function takes more than 3–4 parameters, refactoring should be considered. A long parameter list usually indicates the function is doing too much.

Key Identifiers

  • More than 3–4 parameters
  • Parameters of similar types that are easy to mix up
  • Callers must remember positional ordering
  • Adding a new parameter forces changes at every call site

Refactoring Suggestions

  1. Introduce Parameter Object: Group related parameters into a dedicated object
  2. Preserve Whole Object: Pass the whole object instead of plucking its individual fields
  3. Builder Pattern: Use a builder for constructing complex objects with many optional parts
  4. Split Function: Break one large function into smaller, focused ones

Explanation

A CharacterConfig (or CharacterBuilder) class should encapsulate these parameters to improve readability and reduce the chance of passing arguments in the wrong order.

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
public class CharacterCreator {
public void createCharacter(
String name,
int level,
int health,
int mana,
int strength,
int agility,
int intelligence,
String className,
String race,
int experience,
String weapon,
String armor,
boolean isNPC
) {
// Character creation logic
Character character = new Character();
character.setName(name);
character.setLevel(level);
character.setHealth(health);
character.setMana(mana);
character.setStrength(strength);
character.setAgility(agility);
character.setIntelligence(intelligence);
character.setClassName(className);
character.setRace(race);
character.setExperience(experience);
character.setWeapon(weapon);
character.setArmor(armor);
character.setIsNPC(isNPC);
}
// Another example with even more parameters
public void createAdvancedCharacter(
String name,
int level,
int health,
int mana,
int strength,
int agility,
int intelligence,
int constitution,
int wisdom,
int charisma,
String className,
String race,
String subrace,
int experience,
String primaryWeapon,
String secondaryWeapon,
String helmet,
String armor,
String boots,
String gloves,
String ring1,
String ring2,
String necklace,
boolean isNPC,
boolean isPlayer,
String guild,
int reputation,
String difficulty,
boolean hasMount,
String mountType
) {
// Even more complex character creation logic
Character character = new Character();
// Many setter calls...
character.setName(name);
character.setLevel(level);
// ... and so on
}
// Example of calling the method - shows how unwieldy it becomes
public void demonstrateUsage() {
createCharacter(
"Aragorn", // name
25, // level
150, // health
50, // mana
18, // strength
16, // agility
14, // intelligence
"Ranger", // className
"Human", // race
45000, // experience
"Longsword", // weapon
"Leather Armor", // armor
false // isNPC
);
// Easy to mix up parameters of same type!
createCharacter(
"Legolas",
20,
14, // Oops! Mixed up health and intelligence
30,
120, // This should be health, not strength
20,
16,
"Archer",
"Elf",
35000,
"Elven Bow",
"Elven Cloak",
false
);
}
}
// Supporting class
class Character {
private String name;
private int level;
private int health;
private int mana;
private int strength;
private int agility;
private int intelligence;
private String className;
private String race;
private int experience;
private String weapon;
private String armor;
private boolean isNPC;
// Setters
public void setName(String name) { this.name = name; }
public void setLevel(int level) { this.level = level; }
public void setHealth(int health) { this.health = health; }
public void setMana(int mana) { this.mana = mana; }
public void setStrength(int strength) { this.strength = strength; }
public void setAgility(int agility) { this.agility = agility; }
public void setIntelligence(int intelligence) { this.intelligence = intelligence; }
public void setClassName(String className) { this.className = className; }
public void setRace(String race) { this.race = race; }
public void setExperience(int experience) { this.experience = experience; }
public void setWeapon(String weapon) { this.weapon = weapon; }
public void setArmor(String armor) { this.armor = armor; }
public void setIsNPC(boolean isNPC) { this.isNPC = isNPC; }
// Getters
public String getName() { return name; }
public int getLevel() { return level; }
public int getHealth() { return health; }
public int getMana() { return mana; }
public int getStrength() { return strength; }
public int getAgility() { return agility; }
public int getIntelligence() { return intelligence; }
public String getClassName() { return className; }
public String getRace() { return race; }
public int getExperience() { return experience; }
public String getWeapon() { return weapon; }
public String getArmor() { return armor; }
public boolean isNPC() { return isNPC; }
}