
本文讲解如何将 java 中过度依赖 static 的矩阵填充程序改造为符合面向对象原则的实例化结构,通过移除 static 修饰符、引入构造与实例方法,提升代码可维护性与可测试性。
在原始代码中,所有字段(如 matrix、rows、cols、enemy、target)和方法(如 matrixCreator、recursive、valid、printer)均被声明为 static,导致整个逻辑强耦合于类本身,丧失了面向对象的核心优势:封装、实例独立性与可重用性。例如,若需同时处理多个不同矩阵(如多组测试用例),静态设计将因共享状态而相互干扰。
要正确重构,核心原则是:将数据与行为绑定到对象实例上。具体步骤如下:
- 移除所有 static 修饰符(字段与方法);
- 在 main 中创建类的实例,而非直接调用静态成员;
- 将原 main 中的业务逻辑提取为一个非静态的入口方法(如 run() 或 start()),由实例调用;
- 确保所有字段在实例方法中通过 this 隐式访问(无需显式前缀)。
以下是重构后的完整示例(关键改动已加注释):
public class MatrixRefill {
// ✅ 移除 static:变为实例字段
private String[][] matrix;
private int rows;
private int cols;
private String enemy;
private String target;
public static void main(String[] args) {
// ✅ 在 main 中创建实例,并委托执行
MatrixRefill app = new MatrixRefill();
app.run(args); // 调用实例方法
}
// ✅ 非静态入口方法,接收参数并驱动流程
public void run(String[] args) {
if (args.length < 3) {
throw new IllegalArgumentException("Usage: ");
}
target = args[2];
// 解析位置:如 "2,1" → row=2, col=1
String[] pos = args[1].split(",");
rows = Integer.parseInt(pos[0].trim());
cols = Integer.parseInt(pos[1].trim());
matrix = matrixCreator(args[0]);
enemy = matrix[rows][cols];
recursive(rows, cols, target);
printer(matrix);
}
// ✅ 所有辅助方法均改为实例方法(无 static)
public String[][] matrixCreator(String mx) {
int ro = 0, co = 0;
for (int i = 0; i < mx.length(); i++) {
if (mx.charAt(i) == ',') co++;
else if (mx.charAt(i) == '-') ro++;
}
String[][] matriks = new String[ro + 1][co / 3 + 1]; // 注意:此解析逻辑需与输入格式严格匹配
ro = 0; co = 0;
for (int j = 0; j < mx.length(); j++) {
char c = mx.charAt(j);
if (c == ',') co++;
else if (c == '-') {
ro++; co = 0;
} else if (Character.isLetter(c)) {
matriks[ro][co] = String.valueOf(c);
}
}
return matriks;
}
public void recursive(int row, int col, String target) {
if (valid(row, col)) {
matrix[row][col] = target;
recursive(row + 1, col, target);
recursive(row - 1, col, target);
recursive(row, col + 1, target);
recursive(row, col - 1, target);
}
}
public boolean valid(int row, int col) {
return row >= 0 && row < matrix.length
&& col >= 0 && col < matrix[row].length
&& enemy.equals(matrix[row][col]); // ✅ 使用 equals() 安全比较字符串
}
public void printer(String[][] owo) {
for (int i = 0; i < owo.length; i++) {
for (int j = 0; j < owo[i].length; j++) {
System.out.print(owo[i][j]);
if (j < owo[i].length - 1) System.out.print(" ");
}
System.out.println();
}
}
}
⚠️ 注意事项与优化建议:
- 空指针防护:valid() 中应先检查 matrix != null 和 matrix[row] != null,避免运行时异常;
- 递归深度风险:当前 recursive() 未标记已访问位置,可能导致无限递归或栈溢出——实际应引入 boolean[][] visited 或就地标记(如设为 null 或特殊占位符);
- 输入解析健壮性:args[1] 解析使用 split(",") 比 substring() 更安全;矩阵字符串解析逻辑(如 co/3)需与真实输入格式对齐,建议补充单元测试验证;
- 职责分离:可进一步将矩阵解析、填充逻辑、输出分别封装为独立类(如 MatrixParser、FloodFillEngine),提升可测试性。
重构后,MatrixRefill 成为一个真正可实例化、可复用、可单元测试的组件。例如,你可以在 JUnit 中轻松编写如下测试:
@Test
void testMultipleInstances() {
MatrixRefill m1 = new MatrixRefill();
m1.run(new String[]{"K,K,K-Y,Y,M-M,M,M", "1,1", "S"});
MatrixRefill m2 = new MatrixRefill();
m2.run(new String[]{"A,B-C,D", "0,0", "X"}); // 彼此状态完全隔离
}这才是 Java 面向对象编程的正确实践起点。










