Professional Documents
Culture Documents
– Says nothing about client server systems, we’ll get to this later
View
View Model
model
• You can have many GUI views
View
View Model
model
• You can have many GUI views
• Each view will typically have a corresponding View model class
View
View Model
model
• You can have many GUI views
• Each view will typically have a corresponding View model class
• The Model can be any number of classes, grouped together, used by the View models
View
View Model
model
• Where do we put stuff?
View
View Model
model
User event Business logic
Presentation Take user input
handling Data (data manipulation) GUI state
View
View Model
model
User event Business logic
Take user input
handling Data (data manipulation) GUI state
View
View Model
model
User event Business logic
Take user input
handling Data (data manipulation) GUI state
Presentation
View
View Model
model
User event Business logic
handling Data (data manipulation) GUI state
Presentation
View
View Model
model
User event Business logic
handling Data (data manipulation) GUI state
Presentation
View
View Model
model
Business logic
Data (data manipulation) GUI state
Whenever a button is
clicked, something has to be
User event
done
handling
Presentation
View
View Model
model
Business logic
Data (data manipulation) GUI state
User event
Presentation
handling
View
View Model
model
Business logic
(data manipulation) GUI state
User event
Presentation
handling
View
View Model
model
Business logic
(data manipulation) GUI state
User event
Presentation
handling Data
View
View Model
model
GUI state
User event
Presentation
handling Data
View
View Model
model
GUI state
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Rendering Translation Formatting Networking
JSON)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Rendering Translation Formatting Networking
JSON)
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Rendering Translation Networking
JSON)
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Rendering Translation Networking
JSON)
A Person class with information will
be an object in the Model.
Formatting In the GUI the Person data is put
into different text-fields,
checkboxes, etc.
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Rendering Translation Networking
JSON)
Formatting
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Translation Networking
JSON)
Formatting
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/ Parsing (XML,
data base
Translation Networking
JSON)
Rendering Formatting
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/
data base
Translation Networking
Rendering Formatting
Business logic
Take user input GUI state (data manipulation)
User event
Presentation
handling Data
View
View Model
model
Storage/
data base
Translation Networking
User event
Presentation
handling Data
View
View Model
model
Storage/ Accessing a database, or other
data base
Translation
kind of persistent storage Networking
User event
Presentation
handling Data
View
View Model
model
Translation Networking
Rendering Formatting
Business logic Storage/
Take user input GUI state (data manipulation) data base
User event Parsing (XML,
Presentation
handling Data JSON)
View
View Model
model
Between languages, or
from one valuta to
another. From JSON to
XML. Translation Networking
Rendering Formatting
Business logic Storage/
Take user input GUI state (data manipulation) data base
User event Parsing (XML,
Presentation
handling Data JSON)
View
View Model
model
Networking
View
View Model
model
Connecting a client program to a
server program
Networking
View
View Model
model
Sometimes a part of the Model.
Often a separate “cloud”
Networking
View
View Model
model
Networking
View
View Model
model
Some simple input validation.
Is the input actually a number?
Input Is it in the general form of an email?
validation Is it a phone number?
Networking
View
View Model
model
Does the email already exist?
Does the number actually make
Data sense?
validation Does the name contain numbers?
Input Networking
validation
Rendering Formatting Translation
Business logic Storage/
Take user input GUI state (data manipulation) data base
User event Parsing (XML,
Presentation
handling Data JSON)
View
View Model
model
Input Networking
validation
Rendering Data
Formatting Translation
validation
Business logic Storage/
Take user input GUI state (data manipulation) data base
User event Parsing (XML,
Presentation
handling Data JSON)
View
View Model
model
Input Networking
validation
Rendering Data
Formatting Translation
validation
Business logic Storage/
Take user input GUI state (data manipulation) data base
User event Parsing (XML,
Presentation
handling Data JSON)
View
View Model
model
End of part 1
Life is great
VIA University College
View
View Model
model
View
View Model
model
View
View Model
Has a reference model
View
View Model
Has a reference model Has a reference
Think private
field variable
Bindings
View
View Model
Has a reference model Has a reference
• The View model calls methods on the model
Bindings
View
View Model
Has a reference model Has a reference
Bindings
View
View Model
Has a reference model Has a reference
Bindings
View
View Model
Has a reference model Has a reference
In JavaFX
View
View Model
model
End of part 2
Life is great
VIA University College
View
View Model
model
View1.FXML
View
View1Ctrllr
View1VM
View
model
<<interface>>
DataModel
DataList DataContainer
DataModelImpl
View3
View2
View1
View
View3Ctrllr
View2Ctrllr
View1Ctrllr
View3VM
View2VM
View1VM
View
model
<<interface>>
DataModel
DataList DataContainer
DataModelImpl
View1 View2 View3
View
View1Ctrllr View2Ctrllr View3Ctrllr
<<interface>>
DataModel
DataList DataContainer
DataModelImpl
View1 View2 View3
View
View1Ctrllr View2Ctrllr View3Ctrllr
<<interface>>
DataModel
DataModel2
DataList
DataList2 DataContainer
DataContainer2
Model DataLogic
DataLogic2 LogicHelper
LogicHelper2
DataModelImpl
DataModel2Impl
View1 View2 View3
S O L I D principles
View
View1Ctrllr View2Ctrllr View3Ctrllr
<<interface>> <<interface>>
DataModel2 DataModel
DataList DataContainer
DataModel2Impl DataModelImpl
View1 View2 View3
View
View1Ctrllr View2Ctrllr View3Ctrllr
<<interface>> <<interface>>
DataModel2 DataModel
DataList DataContainer
DataModel2Impl DataModelImpl
MVVM, bind everything together
– We have the core structure of our program, but how is everything started?
When are the classes created?
– Let’s introduce classes responsible for this.
View1 View2 View3
View
View1Ctrllr View2Ctrllr View3Ctrllr
<<interface>> <<interface>>
DataModel2 DataModel
DataList DataContainer
DataModel2Impl DataModelImpl
View1 View2 View3
Just a
placeholder
name
View1VM View2VM View3VM
MyApplication
+ start()
launches <<interface>>
<<interface>>
DataModel2 DataModel
DataList DataContainer
StartApp
+ main() DataLogic LogicHelper
DataModel2Impl DataModelImpl
View1 View2 View3
launches <<interface>>
<<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
View1 View2 View3
launches
ModelFactory <<interface>> <<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
View1 View2 View3
launches
ModelFactory <<interface>> <<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
ModelFactory mf = new ModelFactory();
View1 View2 View3
ViewModelFactory vmf = new ViewModelFactory(mf);
ViewHandler vh = new ViewHandler(vmf);
View1Ctrllr View2Ctrllr View3Ctrllr
JavafX::Applicati ViewHandler
on
launches
ModelFactory <<interface>> <<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
View1 View2 View3
launches
ModelFactory <<interface>> <<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
View1 View2 View3
launches
ModelFactory creates
<<interface>> <<interface>>
DataModel2 DataModel
StartApp
+ main()
DataModel2Impl DataModelImpl
End of part 3
Life is great
VIA University College
OK
If a Property in the
ViewModel is updated, it can
be reflected in the GUI
A 50
B 30
C 20
A = 50%
B = 30%
C = 20%
A 50
B 30
C 20
A = 60%
B = 15%
C = 25%
A 60
B 15
C 25
A = 60%
B = 15% External
modifier
C = 25%
– We’ll start with the Pie Chart view
A = 60%
B = 15% External
modifier
C = 25%
View3
View2
PieChartView
PieChartController
PieChartViewModel
VMFactory
ChartApp
+ start()
<<interface>>
launches DataModel
ModelFactory
StartChartApp
+ main() DataModelImpl
The program
A 60
B 15
C 25
A = 60%
B = 15% External
modifier
C = 25%
View3
View2
PieChartView
PieChartController
PieChartViewModel
VMFactory
ChartApp
+ start()
<<interface>>
launches DataModel
ModelFactory
StartChartApp
+ main() DataModelImpl
View3
View2
PieChartView View3
View2
TextChartView
PieChartController TextChartController
+ init() : void + init() : void
JavafX:: ViewHandler
Application
PieChartViewModel TextChartViewModel
VMFactory
ChartApp
+ start()
<<interface>>
launches
ModelFactory DataModel
StartChartApp
+ main() DataModelImpl
Bindings again
public class PieChartViewModel {
public class PieChartView {
private DoubleProperty x;
@FXML private DoubleProperty y;
Label eventLabel; private DoubleProperty z;
private StringProperty updateTimeStamp;
@FXML
PieChart pieChart;
private Model model;
private PieChartViewModel viewModel; Bind is one direction.
public PieChartViewModel(Model model) {
private PieChart.Data x = new
Changes made in PieChartView::x will
PieChart.Data("X", 0); this.model = model;
private PieChart.Data y = new be pushed to PieChartViewModel::x.
PieChart.Data("Y", 0); x = new SimpleDoubleProperty();
private PieChart.Data z = new PieChart.Data("Z", 0); y = new SimpleDoubleProperty();
But not vice versa z = new SimpleDoubleProperty();
public PieChartView() { updateTimeStamp = new SimpleStringProperty("Last update: ");
} }
public void init(PieChartViewModel pieChartViewModel) { public void updatePieChart() {
this.viewModel = pieChartViewModel;
double[] vals = model.getDataValues();
x.setValue(vals[0]);
x.pieValueProperty().bind(viewModel.xProperty()); If you use the method
y.setValue(vals[1]);
y.pieValueProperty().bind(viewModel.yProperty());
z.pieValueProperty().bind(viewModel.zProperty()); bindBiDirectional, changes are pushed
z.setValue(vals[2]);
updateTimeStamp.setValue("Last updated: " + model.getLastUpdateTim
eventLabel.textProperty().bind(viewModel.updateTimeStampProperty()); }
both was.
ObservableList<PieChart.Data> datas = FXCollections.observableArrayList(x,public
y, z);DoubleProperty xProperty() {
pieChart.setData(datas); return x;
} }
public void onUpdateButton(ActionEvent actionEvent) {
public DoubleProperty yProperty() {
viewModel.updatePieChart();
}
return y;
} }
public DoubleP
return z;
}
Update public StringP
return upd
}
}
public class PieChartViewModel {
public class PieChartView {
private DoubleProperty x;
@FXML private DoubleProperty y;
Label eventLabel; private DoubleProperty z;
private StringProperty updateTimeStamp;
@FXML
PieChart pieChart;
private Model model;
private PieChartViewModel viewModel;
public PieChartViewModel(Model model) {
private PieChart.Data x = new PieChart.Data("X", 0); this.model = model;
private PieChart.Data y = new PieChart.Data("Y", 0); x = new SimpleDoubleProperty();
private PieChart.Data z = new PieChart.Data("Z", 0); y = new SimpleDoubleProperty();
z = new SimpleDoubleProperty();
public PieChartView() { updateTimeStamp = new SimpleStringProperty("Last update: ");
} }
public void init(PieChartViewModel pieChartViewModel) { public void updatePieChart() {
this.viewModel = pieChartViewModel;
double[] vals = model.getDataValues();
x.pieValueProperty().bind(viewModel.xProperty()); x.setValue(vals[0]);
y.pieValueProperty().bind(viewModel.yProperty()); y.setValue(vals[1]);
z.pieValueProperty().bind(viewModel.zProperty()); z.setValue(vals[2]);
updateTimeStamp.setValue("Last updated: " + model.getLastUpdateTi
eventLabel.textProperty().bind(viewModel.updateTimeStampProperty()); }
public DoubleProp
return z;
}
Update public StringProp
return update
}
}
public class PieChart
public class PieChartView {
private DoublePro
@FXML private DoublePro
Label eventLabel; private DoublePro
private StringPro
@FXML
PieChart pieChart;
private Model mod
private PieChartViewModel viewModel;
public PieChartVi
private PieChart.Data x = new PieChart.Data("X", 0); this.model =
private PieChart.Data y = new PieChart.Data("Y", 0); x = new Simpl
private PieChart.Data z = new PieChart.Data("Z", 0); y = new Simpl
z = new Simpl
public PieChartView() { updateTimeSta
} }
public void init(PieChartViewModel pieChartViewModel) { public void updat
this.viewModel = pieChartViewModel;
Update call
x.pieValueProperty().bind(viewModel.xProperty());
double[] vals
x.setValue(va
y.setValue(va
y.pieValueProperty().bind(viewModel.yProperty());
done
z.pieValueProperty().bind(viewModel.zProperty()); z.setValue(va
updateTimeSta
eventLabel.textProperty().bind(viewModel.updateTimeStampProperty()); }
public DoubleProp
return z;
}
Update public StringProp
return update
}
}
Benefits
– It provides separation of concerns. Tightly coupled, change resistant, brittle code causes
all sorts of long-term maintenance issues that ultimately result in poor customer
satisfaction with the delivered software. A clean separation between application logic and
the UI will make an application easier to test, maintain, and evolve. It improves code re-
use opportunities and enables the developer-designer workflow.
– It is a natural pattern for XAML platforms. The key enablers of the MVVM pattern are the
rich data binding stack of the Silverlight platform, and dependency properties. The
combination of these provides the means to connect a UI to a view model.
– It enables a developer-designer workflow. When the UI XAML is not tightly coupled to the
code-behind, it is easy for designers to exercise the freedom they need to be creative
and make a good product.
– It increases application testability. Moving the UI logic to a separate class that can be
instantiated independently of a UI technology makes unit testing much easier.
– https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh848246(v=pandp.10)
End of part 4