Skip to content

Instantly share code, notes, and snippets.

@billy-idle
Last active November 30, 2018 06:50
Show Gist options
  • Save billy-idle/ce742f34105943834e9745db20d2f1e6 to your computer and use it in GitHub Desktop.
Save billy-idle/ce742f34105943834e9745db20d2f1e6 to your computer and use it in GitHub Desktop.
MVC "Pull" Pattern from scratch.
package mvc.from.scratch.pull;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
interface Observer {
void update();
}
public class MVCPullFromScratch {
public static void main(String[] args) {
// The Model doesn't know anything about the controller neither the view.
var rnm = new RandomNumberModel();
// The Controller knows about the Model but not the View.
var rnc = new RandomNumberController(rnm);
// The View knows about the Model and the Controller.
// The View needs a reference to the Model in order to pull the data from it.
var rnv = new RandomNumberView(rnm, rnc);
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.
*/
}
}
abstract class Subject {
private List<Observer> observers = new ArrayList<>();
public void registerObserver(Observer o) {
this.observers.add(o);
}
public void removeObserver(Observer o) {
this.observers.remove(o);
}
protected void notifyObservers() {
this.observers.forEach(Observer::update);
}
public void removeAllObservers() {
this.observers.clear();
}
}
/**
* 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 Subject {
private int number;
private Random random;
public RandomNumberModel() {
this.random = new Random();
}
/**
* Generates an integer random number between 0 and 100,
* notifying its observers.
*/
public void generateRandomNumber() {
this.number = this.random.nextInt(101);
notifyObservers();
}
public int getRandomNumber() {
return this.number;
}
}
/**
* The Controller knows about the Model but not the View.
* Its main purpose is to send commands from the View to the Model.
* ("Commands" change the state of the system and return nothing)
*/
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 RandomNumberModel rnm;
private int position;
public RandomNumberView(RandomNumberModel rnm, RandomNumberController rnc) {
this.rnm = rnm;
this.rnc = rnc;
this.rnm.registerObserver(this);
}
/**
* This is call when the Model calls notifyObservers()
*/
public void update() {
this.getRandomNumber();
this.updatePosition();
this.printRandomNumber();
}
private int getRandomNumber() {
return this.rnm.getRandomNumber();
}
private void updatePosition() {
this.position++;
}
private void printRandomNumber() {
System.out.printf("%-1d. %s%n", this.position, this.getRandomNumber());
}
/**
* Commands are send through the Controller's reference.
*/
public void generateRandomNumber() {
this.rnc.generateRandomNumber();
}
}
@billy-idle
Copy link
Author

billy-idle commented Nov 26, 2018

Class Diagram - MVC "Pull" Pattern From Scratch

mvcpullfromscratch

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