2
votes

I'm learning the MVC pattern right now and I have a short question concerning models and view. I have the following model:

class Person {
  private String name;
  private int age;
}

Now I want my view to ask some input to create a new Person:

public void askPerson() {
  System.out.println("Enter name:");
  //read with System.in
  System.out.println("Enter age:");
  //read with System.in
}

What is now the correct way to create this model. Should I:

1) save the user input in variables in my view and get them in my controller through getters in order to create the model in the controller (getName(), getAge()) or

2) should I create the model in the view and return it as a result of askPerson()?

What is in general the best way to pass such data from the view to the controller?

Thank you!

2
You don't specify which framework you are using. Try reading a Spring MVC or JSF tutorial. - Magnilex
No framework, just three packages for model, view, controller. - freakout

2 Answers

1
votes

The cleanest way is to let controllers listen on the view. In turn the view can tell the controller something needs to happen.

Here is a fully functional example that can be compiled and run

In short it boils down to this.

In this example we assume the controller is already added as an observer to the view.

The view that will notify it's observers (controller).

class CreatePersonView extends Observable implements View {
    public void display() {
        System.out.println("\nWelcome to the create person view!");
        System.out.println("----------------------------------");

        System.out.print("Name: ");
        String name = System.console().readLine().trim();

        System.out.print("Age: ");     
        int age = Integer.valueOf(System.console().readLine().trim());

        Map<String, Object> data = new HashMap<String, Object>();

        data.put("name", name);
        data.put("age", age);

        // generate the event
        setChanged();
        notifyObservers(data);
    }
}

The controller that will consume the event.

class Controller implements Observer {

    PersonService service;

    public void setPersonService(PersonService service) {
        this.service = service;
    }

    // simplified version
    public void update(Observable sender, Object arg) {
        Map data = (Map)arg;
        Person p = service.create((String)data.get("name"), (Integer)data.get("age"));

        //debug
        System.out.println("Created new person: " + p);
    }
}

The main benefit here is that the controller doesn't know anything about the implementation of the view and vice versa. Making them loosely coupled and interchangeable. Which is the whole purpose of MVC.

0
votes

Create your bean object, fill it and send it from View to Controller. A similar post can give you help to write the code. Here is the link:

MVC sending data from View to Controller

Ok as per your request, let me put some code here. This code is created only for the purpose of your understanding. So modify it as per your need and feel free to make any improvements.

Model class

class MyModel {
      private String name;
      private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "MyModel [name=" + name + ", age=" + age + "]";
    }


}

View Class

class MyView {

/**
 * Create view elements, take user inputs and  
 * set the in the model object. Finally send it
 * to the controller for processing
 */


private void onSomeViewEvent(Object myevent) {
    MyModel model = new MyModel();

    // take the properties from event and set in model
    model.setAge(25);
    model.setName("Yourname");

    // send to controller
    MyController controller = new MyController();
    controller.processRequest(model);
}

}

Controller Class

class MyController {

    public void processRequest(MyModel model) {

        /**
         * Inspect the model and process it as per your need.
         */
    }
}