I'm new to the GUI world/OO design pattern and I want to use MVC pattern for my GUI application, I have read a little tutorial about MVC pattern, the Model will contain the data, the View will contain the visual element and the Controller will tie between the View and the Model.
I have a View that contains a ListView node, and the ListView will be filled with names, from a Person Class (Model). But I'm a little confused about one thing.
What I want to know is if loading the data from a file is the responsibility of the Controller or the Model?? And the ObservableList of the names: should it be stored in the Controller or the Model?
There are many different variations of this pattern. In particular, "MVC" in the context of a web application is interpreted somewhat differently to "MVC" in the context of a thick client (e.g. desktop) application (because a web application has to sit atop the request-response cycle). This is just one approach to implementing MVC in the context of a thick client application, using JavaFX.
Your
Person
class is not really the model, unless you have a very simple application: this is typically what we call a domain object, and the model will contain references to it, along with other data. In a narrow context, such as when you are just thinking about theListView
, you can think of thePerson
as your data model (it models the data in each element of theListView
), but in the wider context of the application, there is more data and state to consider.If you are displaying a
ListView<Person>
the data you need, as a minimum, is anObservableList<Person>
. You might also want a property such ascurrentPerson
, that might represent the selected item in the list.If the only view you have is the
ListView
, then creating a separate class to store this would be overkill, but any real application will usually end up with multiple views. At this point, having the data shared in a model becomes a very useful way for different controllers to communicate with each other.So, for example, you might have something like this:
Now you might have a controller for the
ListView
display that looks like this:This controller essentially just binds the data displayed in the list to the data in the model, and ensures the model's
currentPerson
is always the selected item in the list view.Now you might have another view, say an editor, with three text fields for the
firstName
,lastName
, andemail
properties of a person. It's controller might look like:Now if you set things up so both these controllers are sharing the same model, the editor will edit the currently selected item in the list.
Loading and saving data should be done via the model. Sometimes you will even factor this out into a separate class to which the model has a reference (allowing you to easily switch between a file-based data loader and a database data loader, or an implementation that accesses a web service, for example). In the simple case you might do
Then you might have a controller that provides access to this functionality:
Now you can easily assemble an application:
As I said, there are many variations of this pattern (and this is probably more a model-view-presenter, or "passive view" variation), but that's one approach (one I basically favor). It's a bit more natural to provide the model to the controllers via their constructor, but then it's a lot harder to define the controller class with a
fx:controller
attribute. This pattern also lends itself strongly to dependency injection frameworks.Update: full code for this example is here.
For me the model is only responsible of bringing the requiered data structures that represent the bussiness logic of the application.
The action of loading that data from any source should be done by the Controller Layer. You could also use the repository pattern, which can help you in abstracting from the type of source when you are acessing the data from the view. With this implemented you should not care if the Repository implentation is loading the data from file, sql, nosql, webservice ...
For me the ObservableList is part of the View. It is the kind of data structure you can bind to javafx controls. So for example a ObservableList could be populated with Strings from the model but the ObservableList reference should be an attribute of some View´s class. In Javafx its very pleaseant to bind javafx controls with Observable Properties backed by domain objects from the model.
You could also have a look to viewmodel concept. For me a JavaFx bean backed by a POJO could be considered as a view-model, you could see it as a model object ready to be presented in the view. So for example if your view needs to show some total value calculated from 2 model attributes, this total value could be an attribute of the view-model. This attribute would not be persisted and it would be calculated any time you show the view.