Joel Ross
Winter 2017
Model
View
Controller
https://slides.com/joelross/arch-w17-mvc/live
https://github.com/info498e-w17/lec11-mvc
Structure of the Day
-
Admin & Homework
-
MVC: Theory
-
Implementing MVC
-
MVC and the Web
https://slides.com/joelross/arch-w17-mvc/live
https://github.com/info498e-w17/lec11-mvc
https://www.flickr.com/photos/77818424@N06/
Reading Review
Questions/thoughts on "Code Smells" reading?
-
Any smells particularly stinky (or not)?
For Thursday's class: Usability Architectural Patterns (read for the basic argument)
-
Also some textbook stuff on Modeling (squeezing in)
Principle of
Separation of Concerns
"Organize software into separate components (pieces) that are as independent as possible."
Keep the data separate
from the presentation
-
Present same data in different ways
-
Change presentation without needing to change the data
-
Update data once, affect presentation everywhere (all presentations)!
Model-View-Controller
Software architecture that helps separate the data from the presentation of that data.
Model - the data structure that represents the "information"
View - a visual presentation of the model; what the user "sees"
Controller - helps/facilitates the link between the view and the model (and the user!)
MVC Example: Music Player
Model
View
Controller
(View)
MVC Example: A Web Page
Model
View
Controller
JavaScript MVC(ish) Frameworks
See: http://todomvc.com/
Let's talk about the controller...
History: Smalltalk (1980)
Classical (Smalltalk) MVC
User interacts with the controller to manipulate the model.
Classical (Smalltalk) MVC
Model
View
Controller
Alternative MVC
User interacts with the view to modify the model; controller mediates this and connects to storage
Alternate MVC
"Proper" MVC Interaction
-
User interacts with the view
-
View tells controller what to do
-
-
Controller tells model to change state
-
Model changes state, notifies view
-
-
Controller tells view to change state
-
View changes state, asks model for information
-
-
"Proper" MVC Interaction
MVC Key Ideas Quiz!
- The model is the information in the system
- The view is the data structure (e.g., array) for the model
- The controller connects the model and view
- Each model has a single unique view
- Models have no knowledge of their views and are totally independent from them
- Models and views can only talk to the controller, not to each other
- True: False:
- True:
False:
- True: False:
- True: False:
- True:
False:
- True:
False:
Some MVC Variants
-
Model-View-ViewModel (MVVM)
-
Model-View-Presenter (MVP)
-
Model-View-Adapter (MVA)
-
...and more!
Three-Tier Architecture
MVC and Patterns
MVC and Observer Pattern
MVC and Observer Pattern
/* pseudocode! */
//subject
class Model {
register(observer){ }
remove(observer){ }
notifyAll() { }
getState() { }
setState(newState){
this.state = newState;
notifyAll(); //updated!
}
}
//observer
class View {
constructor(model) {
this.model = model;
}
notify() {
display(this.model.getState())
}
}
//registrar/middle-man
class Controller {
constructor(model, view) {
this.model = model;
this.view = view;
//register the observer
this.model.register(view);
}
//when user does stuff
userDoAction(){
//process action...
this.model.setState(newState);
}
}
//execute the program
function main() {
let model = new Model();
let view = new View(model);
let ctrl = new Controller(model, view);
ctrl.userDoAction();
}
MVC and Strategy Pattern
MVC and Strategy Pattern
class View {
constructor(model){
this.model = model;
//view elements
this.button = new Button();
}
setController(controller) {
this.controller = controller;
}
//when button is pressed
performButtonPress(){
//delegate to controller
this.controller.userDoAction();
}
notify() {
display(this.model.getState())
}
//...
}
//registrar/middle-man
class Controller {
constructor(model, view) {
this.model = model;
this.view = view;
view.setController(this); //assign
//observer pattern
this.model.register(view);
}
//when user does stuff
userDoAction(){
//process action...
this.model.setState(newState);
}
}
//execute the program
function main() {
let model = new Model();
let view = new View(model);
let ctrl = new Controller(model, view);
view.performButtonPress();
}
MVC and Composite Pattern
MVC Practice:
Tic-Tac-Toe
Proof of a Good MVC
Is your app skinnable?
Another view!
TypeScript and the Web
TypeScript compiles to plain JavaScript, so it runs great in a webpage!
...except loading modules gets tricky
<!-- Which one to load first?! -->
<script src="dist/model.js"></script>
<script src="dist/view.js"></script>
<script src="dist/controller.js"></script>
<script src="dist/index.js"></script>
Bundling
Solution: bundle (combine) all of the modules into a single file that can be optimized and downloaded at once.
<!-- one file for all your js needs -->
<script src="dist/bundle.js"></script>
Since TypeScript is compiled anyway,
why not compile into a single file?
Bundling with Webpack
# install dependencies (listed in package.json)
npm install
Install Webpack and dependencies
Create webpack.config.js file (included)
Use webpack to compile the code
# global, watch mode
webpack --watch
# installed locally
./node_modules/.bin/webpack --watch
# dev server (auto reload)
webpack-dev-server --inline --open
A jQuery View
display() {
let gamebox = $('#game-box');
gamebox.empty(); //clear old display
// make grid of buttons
for(let i=0; i<this.game.size; i++){ //row
let row = $('<div>'); //a row for the button
for(let j=0; j<this.game.size; j++) {
let player = this.game.getPiece(i,j);
if(player === undefined) player = -1;
let button = $('<button class="btn btn-default">' +
this.playerSymbols[player+1] +
'</button>')
button.click((e) => this.handleClick(i,j)); //closure!!
row.append(button);
}
gamebox.append(row);
}
//show winner, if any
let winner = game.getWinner();
if(winner !== undefined){
this.showWinner(winner)
$('button').attr('disabled','disabled'); //disable all the buttons
}
else {
this.showPrompt(); //show prompt for next move
}
}
ACTION ITEMS!
For next week...
-
Finish the Antz (for realz)
-
Readings (Usability Architectural Patterns; Modeling)
Thursday: See readings!
arch-w17-mvc
By Joel Ross
arch-w17-mvc
- 1,674