← Back to Advanced Java Course | Chapter 6: Design Patterns | Lesson 6 of 14

Java MVC Architecture

The Model

The Model represents the data and business logic of the application -- entities, validation rules, and persistence access all live here. It deliberately has no knowledge of the user interface (the View) or how the application is controlled, which is what keeps the same business logic reusable behind a web UI, a desktop UI, or an API.

Example: The Model

java
public class Main {
	static class UserModel {
		String name;
		UserModel(String name) { this.name = name; } // no knowledge of View or Controller
	}
	public static void main(String[] args) {
		UserModel model = new UserModel("Riya");
		System.out.println(model.name);
	}
}

The View

The View is responsible only for rendering the Model's data to the user -- it should contain presentation logic, not business rules. It receives data from the Controller and displays it appropriately, and in a well-separated MVC design you could swap out the View entirely (say, JSON instead of HTML) without touching the Model.

Example: The View

java
public class Main {
	static class UserView {
		void display(String name) {
			System.out.println("User: " + name); // presentation only, no business rules
		}
	}
	public static void main(String[] args) {
		new UserView().display("Riya");
	}
}

The Controller

The Controller acts as the intermediary between the other two layers: it receives user inputs from the View, translates them into calls on the Model, and then triggers the View to render whatever changed. This is where request handling and coordination logic belongs, kept deliberately thin so business rules stay in the Model.

Example: The Controller

java
public class Main {
	static class UserModel { String name; UserModel(String name) { this.name = name; } }
	static class UserView { void display(String name) { System.out.println("User: " + name); } }
	static class UserController {
		UserModel model; UserView view;
		UserController(UserModel model, UserView view) { this.model = model; this.view = view; }
		void updateView() { view.display(model.name); } // coordinates Model and View
	}
	public static void main(String[] args) {
		UserController controller = new UserController(new UserModel("Riya"), new UserView());
		controller.updateView();
	}
}

Flow of MVC

In an MVC application you construct the Model, View, and Controller and wire them together, usually inside a main method or a framework's startup routine. Understanding this assembly step matters because most bugs in MVC apps come from a Controller reaching into the wrong layer instead of respecting the flow.

Example: Flow of MVC

java
public class Main {
	static class Model { String data = "value"; }
	static class View { void render(String data) { System.out.println("Rendered: " + data); } }
	static class Controller {
		Model model; View view;
		Controller(Model model, View view) { this.model = model; this.view = view; }
		void handle() { view.render(model.data); }
	}
	public static void main(String[] args) {
		Model model = new Model();
		View view = new View();
		Controller controller = new Controller(model, view); // wired together at startup
		controller.handle();
	}
}

Passive vs Active MVC

In an Active MVC design, the View registers itself as an observer of the Model, so when the Model's state changes it notifies the View directly without the Controller mediating every update. This is more efficient for UIs with frequent state changes, but it also means the View now depends on the Model's notification mechanism, a tradeoff worth understanding before choosing it over Passive MVC.

Example: Passive vs Active MVC

java
import java.util.*;
public class Main {
	interface Observer { void onModelChanged(String data); }
	static class ActiveModel {
		List<Observer> observers = new ArrayList<>();
		void subscribe(Observer o) { observers.add(o); }
		void setData(String data) {
			for (Observer o : observers) o.onModelChanged(data); // View notified directly
		}
	}
	public static void main(String[] args) {
		ActiveModel model = new ActiveModel();
		model.subscribe(data -> System.out.println("View updated: " + data));
		model.setData("new state");
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.