MVC在命令行上

时间:2009-12-14 22:59:35

标签: java model-view-controller

我从命令行的角度来看MVC(不是web,没有框架)..简单明了。唯一让我感到困惑的是View的一部分? (好吧,它可能不是唯一的,但它是主要的)

来自IBM站点的

视图具有以下定义

  

该视图提供了   介绍模型。它是   看看应用程序。视图可以   访问模型getter,但它有   不了解二传手。在   此外,它对此一无所知   控制器。该观点应该是   在更改模型时通知   发生。

所以,如果我有以下内容:

模型

查看

  • EditPersonDetails

控制器

  • PersonController

我的人物控制器可以将人物对象传递给EditPeronDetails视图,但是如果我的视图无法访问其设置者,我的视图如何编辑该人,我该如何编辑该人?

视图类也只做一件事吗?即我可以拥有人物视图,其中包含创建,查看,删除,编辑人员的方法

非常感谢

4 个答案:

答案 0 :(得分:10)

将抽象而简单的MVC程序定义为:

interface Model {
    public void setName(String name);
}

interface View {
    public String prompt(String prompt);
}

class Controller {

    private final Model model;
    private final View view;

    public Controller(Model model, View view) {
        this.model = model;
        this.view = view;
    }

    public void run() {
        String name;

        while ((name = view.prompt("\nmvc demo> ")) != null) {
            model.setName(name);
        }
    }
}

然后使用观察者模式(内置自JDK 1.0,see here)以填充具体类:

class Person extends Observable implements Model {

    private String name;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String newName) {
        this.name = newName;
        setChanged();
        notifyObservers(newName);
    }
}

class TUI implements Observer, View { // textual UI

    private final BufferedReader br;

    public TUI(Reader reader) {
        this.br = new BufferedReader(reader);
    }

    public void update(Observable o, Object arg) {
        System.out.println("\n => person updated to " + arg);
    }

    public String prompt(String prompt) {
        try {
            System.out.print(prompt);
            return br.readLine();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}

主要类 负责构建和连接组件:

TUI view = new TUI(new StringReader("David\nDamian\nBob\n"));
Person model = new Person();
model.addObserver(view);
Controller controller = new Controller(model, view);
controller.run();

该计划的输出是:

mvc demo> 
 => person updated to David

mvc demo> 
 => person updated to Damian

...

答案 1 :(得分:8)

是否真的有必要在这里应用3个字母的缩写?如果你必须:

  1. 用户会看到控制台屏幕,其中显示视图(文本行)
  2. 用户在命令行输入内容,甚至来自视图
  3. controller 获取事件,即用户输入
  4. 控制器相应地执行某些操作,并更新模型(人员)
  5. 控制器告诉视图重绘,即打印更多行。
  6. 伪码:

    Person // model
       update();
    
    View
       modelUpdated()
           println(Person.name); ...
    
    Controller
         main()
             while( input = getInput() )
                 person.update(...);
                 view.modelUpdated();
    

答案 2 :(得分:1)

我不确定如何在命令行上转换视图的概念,但我会尝试回答。

  

我的人物控制器可以将人物对象传递到EditPeronDetails视图,但是如果我的视图无法访问其设置者,我的视图如何编辑?如何编辑此人?

没有,控制器会这样做。该视图仅“捕获”新值和操作,并将它们发送到处理它们并更新模型的控制器。

  

视图类也只做一件事吗?即我可以拥有人物视图,其中包含创建,查看,删除,编辑人员的方法

视图可以做多件事。例如,可以使用相同的表单来创建,读取和更新域对象(通过创建和编辑,我的意思是捕获值并将它们发送到控制器)。这实际上是一种非常常见的模式。但正如我所说,这不是执行逻辑的视图,而是控制器。

所以,为了回答你的问题,我想我们可以想象在Person View上有专门的方法来捕获用户输入并处理与控制器的通信,但不能用于CRUD逻辑(我真的想知道你是如何处理的在命令行上与用户交互,对于CRUD应用程序而言似乎不太方便。)

答案 3 :(得分:1)

我正在重新构建一个简单的CLI程序,并向我自己提出了类似的问题。

在研究这一点时,很明显MVC及其衍生物通常被滥用。为了使事情进一步复杂化,存在MVC(Web MVC浮现在脑海中)的变体,这些变体不符合几乎原始的Smalltalk-80实现和MVC的定义。

那就是说,我喜欢dfa's answer但有一点需要注意:用户输入应放在控制器中,而不是视图中。他的回答与Dolphin Smalltalk MVP pattern比MVC更接近。

  

“控制器是一个响应用户输入的组件,例如数据输入和从键盘或鼠标发出的命令。它的职责是充当人与应用之间的桥梁,允许用户与屏幕和数据进行交互。“ - source

因此,我会删除:

return br.readLine();
从视图中

并让控制器等待输入如下:

public void run() {
    view.prompt("\nmvc demo> ");
    String name = br.readLine(); // assume the BufferedReader object is now in the controller
    model.setName(name);
}

说实话,我很难证明这一点必须更好,但我想我会扔掉那里。