Smell Detail

Long Method

过长函数

Bloaters

A function is too long, making it hard to read and maintain—usually a sign multiple responsibilities haven't been split.

Define

Introduction

When a function becomes too long, it's usually handling too many responsibilities. Long functions are harder to understand, test, and maintain. As a rule of thumb, consider splitting a function once it exceeds 20–30 lines.

Key Identifiers

  • Too many lines of code (often more than 20–30)
  • The function performs multiple distinct responsibilities
  • Overall logic is difficult to grasp at a glance
  • Hard to test: requires many scenarios or setup branches

Refactoring Suggestions

  1. Extract Method: Break logical chunks into separate functions
  2. Separate Responsibilities: Ensure each function does exactly one thing
  3. Use Meaningful Names: Make extracted function names express intent clearly

Explanation

This function handles too much: base score calculation, equipment bonuses, skill modifiers, and achievement bonuses. It should be split into several smaller functions, each responsible for a specific calculation step.

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
import java.util.List;
public class ScoreCalculator {
public int calculateScore(Player player) {
int score = 0;
// Calculate base score
score += player.getLevel() * 100;
score += player.getExperience() / 10;
// Calculate equipment bonuses
for (Equipment item : player.getEquipment()) {
if ("weapon".equals(item.getType())) {
score += item.getAttack() * 2;
} else if ("armor".equals(item.getType())) {
score += item.getDefense() * 1.5;
} else if ("accessory".equals(item.getType())) {
score += item.getMagic() * 3;
}
}
// Calculate skill bonuses
for (Skill skill : player.getSkills()) {
if (skill.getLevel() > 5) {
score += skill.getLevel() * skill.getMultiplier();
}
}
// Calculate achievement bonuses
int achievementBonus = 0;
for (Achievement achievement : player.getAchievements()) {
if (achievement.isCompleted()) {
achievementBonus += achievement.getPoints();
}
}
score += achievementBonus * 0.1;
// Apply special rules
if (player.isVIP()) {
score *= 1.5;
}
// Apply time-based bonuses
if (player.getPlayTime() > 1000) {
score += 500;
}
// Apply guild bonuses
if (player.getGuild() != null) {
score += player.getGuild().getBonusPoints();
if (player.getGuild().getRank().equals("Legendary")) {
score *= 1.2;
}
}
// Apply seasonal events bonus
if (isSeasonalEventActive()) {
score += calculateSeasonalBonus(player);
}
// Apply level milestone bonuses
if (player.getLevel() >= 50) {
score += 1000;
}
if (player.getLevel() >= 100) {
score += 2000;
}
// Apply difficulty modifier
String difficulty = player.getDifficulty();
if ("hard".equals(difficulty)) {
score *= 1.3;
} else if ("nightmare".equals(difficulty)) {
score *= 1.5;
} else if ("hell".equals(difficulty)) {
score *= 2.0;
}
// Ensure score is not negative
if (score < 0) {
score = 0;
}
return score;
}
private boolean isSeasonalEventActive() {
// Check if seasonal event is currently active
return true; // Simplified for example
}
private int calculateSeasonalBonus(Player player) {
// Calculate seasonal event bonus
return player.getLevel() * 10;
}
}
// Supporting classes for demonstration
class Player {
private int level;
private int experience;
private int playTime;
private boolean isVIP;
private String difficulty;
private List<Equipment> equipment;
private List<Skill> skills;
private List<Achievement> achievements;
private Guild guild;
// Getters
public int getLevel() { return level; }
public int getExperience() { return experience; }
public int getPlayTime() { return playTime; }
public boolean isVIP() { return isVIP; }
public String getDifficulty() { return difficulty; }
public List<Equipment> getEquipment() { return equipment; }
public List<Skill> getSkills() { return skills; }
public List<Achievement> getAchievements() { return achievements; }
public Guild getGuild() { return guild; }
}
class Equipment {
private String type;
private int attack;
private int defense;
private int magic;
public String getType() { return type; }
public int getAttack() { return attack; }
public int getDefense() { return defense; }
public int getMagic() { return magic; }
}
class Skill {
private int level;
private double multiplier;
public int getLevel() { return level; }
public double getMultiplier() { return multiplier; }
}
class Achievement {
private boolean completed;
private int points;
public boolean isCompleted() { return completed; }
public int getPoints() { return points; }
}
class Guild {
private String rank;
private int bonusPoints;
public String getRank() { return rank; }
public int getBonusPoints() { return bonusPoints; }
}