有很多方法可以构建可以接受不同求解器和视图的此类应用程序。我将尝试演示一个非常基本的、精简的,以使其尽可能简单。
为此,我们将使用一个求解器来计算某个形状的周长并绘制解。
首先,我们将定义一些接口,稍后会更清楚地了解它们的使用:
interface Model{
boolean solve();
int solution();
boolean isSolved();
}
interface View{
void draw(Graphics g);
}
interface Solver {
Model getModel();
View getView();
}
使用这些接口,我们将定义 Model、View 和 C控制器以支持计算周长一个正方形。
模型封装了信息(属性和状态)和逻辑:
class SquarePrimeterModel implements Model{
private final int edgeLength;
private int perimeter;
private boolean isSolved = false;
public SquarePrimeterModel(int edgeLength) {
this.edgeLength = edgeLength;
}
@Override
public boolean solve() {
perimeter = 4 * edgeLength;
isSolved = true;
return true;
}
@Override
public int solution() {
return perimeter;
}
@Override
public boolean isSolved() {
return isSolved;
}
//edgeLength is a unique property for this model
public int getEdgeLength() {
return edgeLength;
}
}
视图的职责,顾名思义就是生成视图:
class SquarePrimeterView implements View{
private final static int xOffset = 50, yOffset = 50, GAP = 20;
private final SquarePrimeterModel model;
public SquarePrimeterView(SquarePrimeterModel model) {
this.model = model;
}
@Override
public void draw(Graphics g) {
if(model.isSolved()){
g.drawRect(xOffset, yOffset, model.getEdgeLength(), model.getEdgeLength());
String text = "Edge =" + model.getEdgeLength() + " Perimiter ="+ model.solution();
int yPosition = yOffset + model.getEdgeLength()+ GAP;
g.drawString(text, xOffset, yPosition);
}
}
}
控制器构建、配置和管理模型和视图:
class SquarePrimeterController implements Solver{
private final SquarePrimeterModel model;
private final View view;
public SquarePrimeterController(int edgeLength) {
model = new SquarePrimeterModel(edgeLength);
view = new SquarePrimeterView(model);
}
@Override
public Model getModel() {
return model;
}
@Override
public View getView() {
return view;
}
}
如果我们需要另一个求解器,例如计算三角形周长的求解器,我们只需编写与 SquarePrimeter 类非常相似的 TriangelPrimeterController、TriangelPrimeterModel 和 TriangelPrimeterView。
我们需要的最后一段代码是使用SquarePrimeterController的应用程序:
public class SwingMVCSolveController {
public SwingMVCSolveController() {
Solver solver = new SquarePrimeterController(150);//todo: select solver by gui
solver.getModel().solve(); //todo start solve by gui
new MainView(solver.getView());
}
public static void main(String[] args) {
new SwingMVCSolveController();
}
}
class MainView extends JPanel {
private static final Dimension size = new Dimension(400, 400);
private final View solverView;
public MainView(View view) {
solverView = view;
createAndShowGui();
}
private void createAndShowGui() {
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add (this);
frame.pack();
frame.setVisible (true);
}
@Override
public Dimension getPreferredSize() {
return size;
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
solverView.draw(g);
}
}
显然Solver solver = new SquarePrimeterController(150); 可以更改为Solver solver = new TrianglePrimeterController(150); 或Solver 的任何其他实现。
完整的可运行代码可用here