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/
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2192359/21403306696_a48efe462c_z.jpg)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3370128/071310_1919_Legosorting1.jpg)
"Organize software into separate components (pieces) that are as independent as possible."
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193148/recall-stamp.png)
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!)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1873739/Picture1.png)
MVC Example: Music Player
Model
View
Controller
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193204/50-1-1.png)
(View)
MVC Example: A Web Page
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1767014/Screen_Shot_2015-09-27_at_1.20.48_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1767031/Screen_Shot_2015-09-26_at_8.31.06_PM_2.png)
Model
View
Controller
JavaScript MVC(ish) Frameworks
See: http://todomvc.com/
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1873797/Screen_Shot_2015-10-25_at_9.02.42_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1765091/AngularJS_logo.svg.png)
Let's talk about the controller...
History: Smalltalk (1980)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3468764/500004472-03-01.jpeg)
Classical (Smalltalk) MVC
User interacts with the controller to manipulate the model.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1875698/Slide3.jpg)
Classical (Smalltalk) MVC
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193274/lisa.jpg)
Model
View
Controller
Alternative MVC
User interacts with the view to modify the model; controller mediates this and connects to storage
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/1875702/Slide4.jpg)
Alternate MVC
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3468784/model_view_controller_2x.png)
"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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193312/Screen_Shot_2016-02-01_at_12.41.13_PM.png)
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!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193348/icecreamflavors.jpg)
Three-Tier Architecture
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193353/3tier.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3468816/sneak-preview.png)
MVC and Patterns
MVC and Observer Pattern
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193365/Screen_Shot_2016-02-01_at_12.56.52_PM.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193372/Screen_Shot_2016-02-01_at_12.57.14_PM.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3468847/Screen_Shot_2017-02-06_at_8.45.01_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/2193384/thinking-in-react-components.png)
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?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/377018/images/3199431/687474703a2f2f7765627061636b2e6769746875622e696f2f6173736574732f6c6f676f2e706e67.png)
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,687