Skip to content

Instantly share code, notes, and snippets.

@billy-idle
Created November 26, 2018 01:19
Show Gist options
  • Save billy-idle/36713da0d954bc2f988a928739e6b439 to your computer and use it in GitHub Desktop.
Save billy-idle/36713da0d954bc2f988a928739e6b439 to your computer and use it in GitHub Desktop.
MVC "Pull" Pattern.
package mvc.java.pull;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;
public class MVCPull {
public static void main(String[] args) {
// The Model doesn't know anything about the controller neither the view
RandomNumberModel rnm = new RandomNumberModel();
// The Controller knows about the Model but not the View
RandomNumberController rnc = new RandomNumberController(rnm);
// The View knows about the Controller and has a reference to the Model in the update() method.
RandomNumberView rnv = new RandomNumberView(rnc);
// The Observable (Model) registers the observer (View)
rnm.addObserver(rnv);
int i = 0;
while (i < 5) {
/*
Imagine that this could be an ActionEvent
triggered by some Button. i.e. "generateRandomNumberButton"
*/
rnv.generateRandomNumber();
i++;
}
/*
Output
1. 66
2. 17
3. 75
4. 94
5. 39
*The output will vary because its randomness.
*/
}
}
/**
* In general, in the MVC pattern all the dependencies point to the Model.
* The Model doesn't know anything about the controller neither the view.
*/
class RandomNumberModel extends Observable {
private Random random;
private int number;
public RandomNumberModel() {
this.random = new Random();
}
/**
* Generates an integer random number between 0 and 100,
* notifying its observers and passing its state.
*/
public void generateRandomNumber() {
this.number = this.random.nextInt(101);
setChanged();
notifyObservers(); // Pushes "this" by default.
}
public int getRandomNumber() {
return number;
}
}
/**
* The Controller knows about the Model but not the View
*/
class RandomNumberController {
private RandomNumberModel rnm;
public RandomNumberController(RandomNumberModel rnm) {
this.rnm = rnm;
}
/**
* Encapsulates the call. ("Tell", don't "Ask" Principle)
*/
public void generateRandomNumber() {
this.rnm.generateRandomNumber();
}
}
/**
* Because the "Observer Pull Pattern" the View knows
* about the Controller and the Model.
*/
class RandomNumberView implements Observer {
private RandomNumberController rnc;
private int position;
private int randomNumber;
public RandomNumberView(RandomNumberController rnc) {
this.rnc = rnc;
this.position = 1;
}
public void generateRandomNumber() {
this.rnc.generateRandomNumber();
}
/**
* @param o MVCPullFromScratch.RandomNumberModel Object
* @param arg Integer random number (The Model "pushes" its state)
*/
public void update(Observable o, Object arg) {
this.randomNumber = ((RandomNumberModel) o).getRandomNumber(); // <- o is casted
this.updatePosition();
this.printRandomNumber();
}
private void updatePosition() {
this.position++;
}
/**
* Prints the number to the standard output stream
*/
private void printRandomNumber() {
System.out.printf("%-1d. %s\n", this.position, this.randomNumber);
}
}
@billy-idle
Copy link
Author

Class Diagram - MVC "Pull" Pattern

mvcpull

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment