You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在迷宫生成求解程序中支持并绘制多种不同的求解算法

优化方案:采用绘制策略模式解耦绘制逻辑与JPanel实现

核心思路

将不同求解器的绘制逻辑、对应所需的参数全部封装到独立的绘制策略类中,JPanel仅依赖统一的绘制接口,无需感知不同求解器的参数差异,也不需要创建多份JPanel子类。

具体实现步骤

1. 定义统一绘制接口

首先抽象所有求解器绘制逻辑的公共行为,定义接口:

public interface MazeSolverDrawer {
    // 统一传入绘图上下文和基础迷宫对象,其余参数由实现类自行持有
    void draw(Graphics g, Maze baseMaze);
}

2. 每个求解器实现专属绘制策略

不同求解器的实现类自行存储所需的所有参数,实现接口的draw方法完成专属绘制逻辑:

// 求解器1的绘制实现
public class Solver1Drawer implements MazeSolverDrawer {
    // 存储求解器1绘制需要的所有个性化参数
    private List<Point> visitedPath;
    private Queue<Point> pendingNodes;
    private int currentStep;

    // 构造方法传入所有需要的参数
    public Solver1Drawer(List<Point> visitedPath, Queue<Point> pendingNodes, int currentStep) {
        this.visitedPath = visitedPath;
        this.pendingNodes = pendingNodes;
        this.currentStep = currentStep;
    }

    @Override
    public void draw(Graphics g, Maze baseMaze) {
        // 此处编写求解器1专属的子步骤绘制逻辑,参数均由当前类持有,可直接使用
    }
}

// 求解器2的绘制实现,可自由定义需要的参数
public class Solver2Drawer implements MazeSolverDrawer {
    private Stack<Point> backtrackStack;
    private boolean[][] visitedMark;

    public Solver2Drawer(Stack<Point> backtrackStack, boolean[][] visitedMark) {
        this.backtrackStack = backtrackStack;
        this.visitedMark = visitedMark;
    }

    @Override
    public void draw(Graphics g, Maze baseMaze) {
        // 求解器2的绘制逻辑
    }
}

3. 简化JPanel实现

JPanel仅保留基础绘制逻辑和统一的绘制策略入口,不需要switch分支,也不需要存储不同求解器的参数:

public class MazePanel extends JPanel {
    private Maze maze;
    // 持有当前使用的绘制策略实例
    private MazeSolverDrawer currentSolverDrawer;

    // 对外提供方法,切换求解器/更新求解状态时传入对应绘制策略即可
    public void setCurrentSolverDrawer(MazeSolverDrawer drawer) {
        this.currentSolverDrawer = drawer;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // 绘制基础迷宫
        drawMaze(g);
        // 存在绘制策略时调用其绘制方法
        if (currentSolverDrawer != null) {
            currentSolverDrawer.draw(g, maze);
        }
    }

    private void drawMaze(Graphics g) {
        // 原有基础迷宫绘制逻辑
    }
}

扩展优化(Java 8+适用)

如果不想为每个求解器单独创建实现类,可直接用Lambda表达式实现MazeSolverDrawer接口,在求解器运行更新状态时直接传入绘制逻辑:

// Solver1运行过程中更新绘制状态时的调用示例
List<Point> currentVisited = ...;
Queue<Point> currentPending = ...;
int step = ...;
mazePanel.setCurrentSolverDrawer((g, maze) -> {
    // 直接编写Solver1的绘制逻辑,外部的currentVisited等变量只要是final或等效final即可直接使用
});

方案优势

  • 无需创建多份JPanel子类,全局仅需一份MazePanel实现
  • 新增求解器时不需要修改原有JPanel代码,符合开闭原则
  • 求解器的参数与绘制逻辑内聚在各自的实现类中,不会在JPanel中堆积冗余成员变量
  • 完全符合Swing的绘制规范,所有绘制逻辑均在paintComponent中执行,性能更稳定

内容的提问来源于stack exchange,提问作者Szász Erik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:15:08