1

I've implemented a student administration with MVC pattern (Tutorial: Link). I've decided to divid the students in "SingleStudentModel" and "MultipleStudentModel", but I'm not sure if that make sense in my case. In general, I'm not satisfied with my solution. Is it possible to handle single student and multiple students with one controller? Is it ok if a model import into a view class (see StudentsView.java)?

How can I improve this project?

Thanks in advance.

Student.java (Model, data class (?))

public class Student {

    private String name;
    private int nr;

    public Student(String _name, int _nr){
        this.name = _name;
        this.nr = _nr;
    }

    // get set
}

SingleStudentModel.java (Model)

public class SingleStudentModel {
    private Student student;

    // get set
}

StudentController.java (Controller -> SingleStudentModel)

public class StudentController {
    private SingleStudentModel model;
    private StudentView view;

    public StudentController(SingleStudentModel _model, StudentView _view){
        this.model = _model;
        this.view = _view;
    }

   // set get

    public void updateView(){
        view.printStudentDetails(model.getStudent().getName(), model.getStudent().getNr());
    }
}

MultipleStudentModel.java (Model)

public class MultipleStudentModel {
    private Collection<Student> students = new ArrayList<Student>();

    public Collection<Student> getStudents() {
        return students;
    }

    public void setStudents(Student student){
        this.students.add(student);
    }
}

StudentsController.java (Controller -> StudentsModel)

public class StudentsController {
    private MultipleStudentModel model;
    private StudentsView view;

    public StudentsController(MultipleStudentModel _model, StudentsView _view){
        this.model = _model;
        this.view = _view;
    }

    public void updateView(){
        view.printStudentList(model.getStudents());
    }
}

StudentView.java

public class StudentView {
    public void printStudentDetails(String _name, int _nr){
        System.out.println("Student: ");
        System.out.println("name: " + _name);
        System.out.println("nr: " + _nr);
    }
}

StudentsView.java

import com.mvc.model.Student;

import java.util.Collection;

public class StudentsView {

    public void printStudentList(Collection<Student> students){

        System.out.println("\nStudent list");

        for(Student item : students){
            System.out.println("name: " + item.getName());
            System.out.println("nr: " + item.getNr());
        }
    }
}

Main.java

 public class Main {

       public static void main(String [] args){

            //Single student
            SingleStudentModel model = new SingleStudentModel();
            StudentView view = new StudentView();
            StudentController controller = new StudentController(model, view);

            model.setStudent(new Student("John", 1));

            controller.updateView();

            //Multiple student
            MultipleStudentModel model2 = new MultipleStudentModel();
            StudentsView view2 = new StudentsView();
            StudentsController controller2 = new StudentsController(model2, view2);

            model2.setStudents(new Student("Zelda", 2));
            model2.setStudents(new Student("Link", 3));

            controller2.updateView();

            }
      }
1
  • This seems more like a code review question. I would suggest you post such questions to codereview.stackexchange.com instead of to Stack Overflow. Commented Apr 28, 2018 at 9:04

3 Answers 3

2

you can create an interface of model so both classes MultipleStudentModel and SingleStudentModel will implement

so you don't need to define two controller that basically share the same logic, also this will let you change controller behaviour at runtime with setModel

this will also create a contract to bind your model to specific methods like get and such (insert/update/delete)

public class StudentController {
    private Model model;
    private StudentView view;

    public StudentController(Model _model, StudentView _view){
        this.model = _model;
        this.view = _view;
    }

    public setModel(Model model){
         this.model = model;
    }


}

you can do it also with the View classes

also, basically one student is just a list of students contains only one element, you can remove that redundancy

Sign up to request clarification or add additional context in comments.

Comments

1

There is some advice:

1. use interface instead of class.

You may have heard of Interface-based programming, which is a better way if you have more than one implementation of same kind object, like model and view in this example. So a better way is to abstract these two to interfaces instead of classes:

StudentView.java

import java.util.List;

public interface StudentView {
    void printStudentList(List<Student> students);
}

StudentModel.java

import java.util.List;

public interface StudentModel {
    List<Student> getStudents();
}

it's convenient to implement them whenever you want.

2. if you want to control multiple model-view couples in one controller, it's available to use a Map<K, V> to access.

StudentController.java

import java.util.HashMap;
import java.util.Map;

public class StudentController {
    //    private StudentModel model;
    //    private StudentView view;

    private Map<StudentModel, StudentView> modelAndViews;  // store model-view couple

    public StudentController() {
        this.modelAndViews = new HashMap<>();
    }
    public void updateView(StudentModel model) {
        StudentView v = this.modelAndViews.get(model);
        if (v == null)  return; 
        v.printStudentList(model.getStudents());
    }
    public void addModelAndView(StudentModel model, StudentView view) {
        // validate for null pointer
        // if (...)
        this.modelAndViews.put(model, view); // add new model-view couple
    }
    // other methods
}

3. implement POJO's toString() method is a good way to test your code, rather than doing it in other methods.

Student.java

public class Student {
    private String name;
    private int rollNo;
    public Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getRollNo() {
        return rollNo;
    }
    public void setRollNo(int rollNo) {
        this.rollNo = rollNo;
    }
    @Override
    public String toString() {
        return "Student (name=" + name + ", rollNo=" + rollNo + ")";  // for testing
    }
}

Here are implementations of model and view :

SingleStudentModel.java

import java.util.List;

public class SingleStudentModel implements StudentModel {

    private List<Student> students; // store one student;   
    
    public SingleStudentModel(List<Student> students) {
        this.students = students;
    }
    @Override
    public List<Student> getStudents() {
        return this.students;
    }
}

MultipleStudentModel.java

import java.util.List;

public class MultipleStudentModel implements StudentModel {

    private List<Student> students;
    
    public MultipleStudentModel(List<Student> students) {
        this.students = students;
    }
    @Override
    public List<Student> getStudents() {
        return this.students;
    }
}

SingleStudentView.java

import java.util.List;

public class SingleStudentView implements StudentView {

    @Override
    public void printStudentList(List<Student> students) {
        Student s = students.get(0);
        System.out.println(s);
    }
}

MultipleStudentView.java

import java.util.List;

public class MultipleStudentView implements StudentView {

    @Override
    public void printStudentList(List<Student> students) {
        for (Student s : students) {
            System.out.println(s);
        }
    }
}

(these two views can be combined into one, while two are easier to understand:) )

at last, it's main class:

Main.java

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        
        List<Student> singleStudentList = new ArrayList<>();
        List<Student> multipleStudentList = new ArrayList<>();
        // add test cases
        singleStudentList.add(new Student("s1", 1));
        for (int i = 0; i < 5; i++) {
            multipleStudentList.add(new Student("s" + i, i));
        }
        
        StudentModel singleStudentModel = new SingleStudentModel(singleStudentList);
        StudentModel multipleStudentModel = new MultipleStudentModel(multipleStudentList);
        
        StudentView singleStudentView = new SingleStudentView();
        StudentView multipleStudentView = new MultipleStudentView();
        
        
        StudentController controller = new StudentController();
        
        controller.addModelAndView(singleStudentModel, singleStudentView);
        controller.addModelAndView(multipleStudentModel, multipleStudentView);
        
        System.out.println("---------- update single student's view ---------------");
        controller.updateView(singleStudentModel);
        System.out.println("---------- update multiple students' views ---------------");
        controller.updateView(multipleStudentModel);
    }
}

solution:

---------- update single student's view ---------------
Student (name=s1, rollNo=1)
---------- update multiple students' views ---------------
Student (name=s0, rollNo=0)
Student (name=s1, rollNo=1)
Student (name=s2, rollNo=2)
Student (name=s3, rollNo=3)
Student (name=s4, rollNo=4)

code structure:

-src
├ view
│  ├ MultipleStudentView.java
│  ├ SingleStudentView.java
│  └ StudentView.java
├ model
│  ├ MultipleStudentModel.java
│  ├ SingleStudentModel.java
│  ├ Student.java
│  └ StudentModel.java
├ controller
│  └ StudentController.java
└ Main.java
 

These are all the codes here, hope help~

(By the way, in typical JavaEE development, model is only POJO, and view is more commonly logic view like String. This is only an example of MVC for understanding.)

Comments

0

from my knowledge of MVC approach, you should not even have functionality on the Model... so there are some core mistakes here.

you should consider putting all functions in the View or in the Controller, and let them handle the things. View should throw events, and Controller should handle them.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.