MVC Architecture pattern
MVC is a widely used architectural pattern in software design that separates an application into three interconnected components, each handling a specific aspect of the application's logic:
Model
Represents the application's data and business logic
Manages the state, rules, and operations of the data
Independent of the user interface
Responsible for storing, processing, and managing data
Notifies Views and Controllers about any changes in its state
View
Handles the presentation layer of the application
Renders the user interface and displays data to the user
Receives data from the Model to present
Typically passive, meaning it just displays information
Can send user actions to the Controller
Controller
Acts as an intermediary between the Model and View
Processes incoming user requests
Manipulates the Model based on user input
Updates the View with new data from the Model
Manages the flow of data and user interactions
How MVC Works:
User interacts with the View (e.g., clicking a button)
Controller receives the user action
Controller updates the Model based on the action
Model processes the data and updates its state
Model notifies the View of the changes
View retrieves updated data from the Model and refreshes the display
Benefits of MVC:
Separates concerns, making the code more modular
Improves code reusability and maintainability
Allows parallel development of components
Easier to modify or replace individual components
Supports multiple Views for the same Model
Class Diagram
Code:
// Model Interface
interface Model {
fun getData(): Any?
fun setData(data: Any?)
fun updateState()
fun notifyObservers()
}
// View Interface
interface View {
fun render()
fun updateDisplay(data: Any?)
fun handleUserInput()
}
// Controller Interface
interface Controller {
fun processUserAction()
fun updateModel(data: Any?)
fun selectView()
}
// Concrete Model Implementation
class UserModel : Model {
private var userData: MutableMap<String, Any> = mutableMapOf()
private val observers: MutableList<View> = mutableListOf()
override fun getData(): MutableMap<String, Any> {
return userData
}
override fun setData(data: Any?) {
if (data is Map<*, *>) {
userData.putAll(data as Map<String, Any>)
notifyObservers()
}
}
override fun updateState() {
// Example of updating internal state
userData["lastUpdated"] = System.currentTimeMillis()
notifyObservers()
}
override fun notifyObservers() {
observers.forEach { it.updateDisplay(userData) }
}
fun addObserver(view: View) {
observers.add(view)
}
fun removeObserver(view: View) {
observers.remove(view)
}
}
// Concrete View Implementation
class UserConsoleView : View {
private var currentData: Map<String, Any>? = null
override fun render() {
println("Rendering User View")
currentData?.let { displayUserData(it) }
}
override fun updateDisplay(data: Any?) {
if (data is Map<*, *>) {
currentData = data as Map<String, Any>
render()
}
}
override fun handleUserInput() {
println("Handling user input...")
// Simulate user input
val simulatedInput = mapOf(
"name" to "John Doe",
"email" to "[email protected]"
)
// In a real app, this would be connected to actual user input
}
private fun displayUserData(data: Map<String, Any>) {
println("User Data:")
data.forEach { (key, value) ->
println("$key: $value")
}
}
}
// Concrete Controller Implementation
class UserController(
private val model: UserModel,
private val view: UserConsoleView
) : Controller {
init {
// Register view as an observer of the model
model.addObserver(view)
}
override fun processUserAction() {
// Simulate processing a user action
val newUserData = mapOf(
"name" to "Jane Smith",
"age" to 30,
"email" to "[email protected]"
)
updateModel(newUserData)
}
override fun updateModel(data: Any?) {
// Update the model with new data
model.setData(data)
}
override fun selectView() {
// In a more complex app, this might choose between different views
view.render()
}
// Demonstration method to show MVC flow
fun rundemonstration() {
// Initial state
println("Initial State:")
selectView()
// Process user action
println("\nProcessing User Action:")
processUserAction()
}
}
// Main function to demonstrate the MVC pattern
fun main() {
// Create MVC components
val model = UserModel()
val view = UserConsoleView()
val controller = UserController(model, view)
// Run the demonstration
controller.rundemonstration()
}
Last updated