added description of ui architecture pattern used

This commit is contained in:
Manfred Karrer 2014-08-28 19:34:47 +02:00
parent fb89f087f0
commit d30a41b54b
5 changed files with 96 additions and 65 deletions

View File

@ -1,23 +0,0 @@
## UI Architecure pattern:
We use the Presentation Model pattern which has some similarities with MVVM (Silverlight, WPF) as we use data
bindings, though there are differences in the way the view and the "code behind" is organized (different framework
support).
We don't use the term controller for the JavaFX controller it has too much association with the classical MVC
controller.
View: FXML or code based View
CodeBehind (CB): JavaFX controller associated with FXML View
Presentation Model (PM)
Model: Domain data
* State is stored in the presenter.
* Logic is stored in presenter.
* Presenter represents a abstract view of the UI.
* Presenter is not aware of the view.
* View is aware of the presenter.
* View is completely isolated from the model.
## References:
[Presentation Model](http://martinfowler.com/eaaDev/PresentationModel.html)
[Model View ViewModel - MVVM](http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)

92
UI-development-notes.md Normal file
View File

@ -0,0 +1,92 @@
## UI Architecure pattern:
We use a variant of the **Presentation Model** pattern which has some similarities with the **Model View ViewModel**
(MVVM used in Silverlight and WPF) as we use data bindings, though there are differences in the way the view and
the "code behind" is organized (due to different framework features/support).
We don't use the term controller for the JavaFX controller it has too much association with the classical MVC
controller.
The described pattern is only applied yet to that package:
io.bitsquare.gui.trade.createoffer;
For prototyping the UI we stick first with a more rapid development style approach.
###Elements
* View
* CodeBehind (CB)
* Presentation Model (PM)
* Model
#####Overview:
* View/CB is responsible for the visual representation. No logic. No state.
* Presentation model holds the view/CB state.
* Presentation model handles view specific logic.
* Presentation model does validation of user in put and formatting of domain data.
* Model is the domain specific representation of the view. It holds domain data and handles domain logic.
###View
Typically FXML is used.
It knows the CodeBehind (fx:controller)
#####Responsibility:
* Defines visible parts of the UI
* Define UI element properties
* Layout
* Style
* Event handler definition
###CodeBehind (CB)
It is conceptually part of the view layer. It adds functionality which cannot be expressed in the declarative FXML
format.
It is the JavaFX controller associated with the FXML view, but we don't use the term controller as it has too much
association with the classical MVC controller. It gets created by the JavaFX framework (FXMLLoader) and also the
setup with the FXML view is done by the framework.
It knows the presentation model but not the model.
#####Responsibility:
* Creates presentation model and passes model from Guice injection to the presenter (might be changed).
* Setup binding for updates from PM to view elements (also bidirectional for used for input data).
* Those binding are only simple bindings to plain presenter properties, no logical bindings.
* Listens to UI events (Actions) from UI controls and calls method in presentation model.
* Is entry node for view graph and responsible for navigation and for creation of new views.
* Passes application method calls to PM. Calls application methods on sub views.
* Handle lifecycle and self removal from scene graph.
* Can contain non-declarative (dynamic) view definitions (if that gets larger, then use a dedicated ViewBuilder)
* Has **no logic** and **no state**!
###Presentation model (PM)
It is the abstraction/presentation of the view.
Can be used for unit testing.
It knows the model but it does not know the CodeBehind (View)
#####Responsibility:
* Holds the state of the view/CB
* Formats domain data to the needed representation for the view/CB.
* Receive user input via method calls from CodeBehind.
* Validates UI input, applies business logic and converts (parse) input to model.
* Listen to updates from model via bindings.
###Data model
Represents the domain scope which is handled by the view.
Is interface to application domain objects.
We use Guice for dependency injection of the application domain objects.
Can be used for unit testing.
Does not know the PM and View/CB
#####Responsibility:
* Holds domain data for that view
* Apply domain business logic
* Interacts with application domain objects
* It only covers the domain represented by that view and not a lower level domain.
## References:
[Presentation Model](http://martinfowler.com/eaaDev/PresentationModel.html)
[Model View ViewModel - MVVM](http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)

View File

@ -42,31 +42,6 @@ import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Code behind (We don't call it controller as controller is associated with the classical MVC controller):
* <p>
* - Knows the presentation model, does not know the model
* - Has no logic and no state
* <p>
* - Creates presentation model and passes model from Guice injection to the presenter. Does not hold any reference to the model.
* //TODO is there a better way for DI of model?
* - Setup binding from presenter to view elements (also bidirectional - used for input data). Binding are only to plain
* presenter properties. There are no logical bindings or cross-view element bindings.
* - Listens to UI events (Actions) from view and calls method in presentation model.
* - Is entry node for view graph and responsible for navigation and creation of new views.
* - Passes application API method calls to Presenter. Calls application methods on sub views.
* - Handle lifecycle and self removal from scene graph.
* - Can contain non-declarative (dynamic) view definitions (if it gets larger, then use a dedicated ViewBuilder)
* <p>
* View:
* - Typically declared in FXML. Dynamic parts are declared in Controller. If more view elements need to be defined in
* code then use a ViewBuilder.
* <p>
* ViewBuilder (optional):
* - Additionally or instead of FXML view. If no FXML then controller setup need to be handles by ViewBuilder.
* <p>
* Note: Don't assign the root node as it is defined in the base class!
*/
public class CreateOfferCB extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(CreateOfferCB.class);
@ -88,6 +63,7 @@ public class CreateOfferCB extends CachedViewController {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
//TODO find a better solution, handle at base class?
@Inject
public CreateOfferCB(CreateOfferModel model) {
pm = new CreateOfferPM(model);

View File

@ -52,12 +52,9 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Data model:
* Does not know the Presenter and View (CodeBehind)
* Use Guice for DI to get domain objects
* <p>
* - Holds domain data
* - Apply business logic (no view related, that is done in presenter)
* Domain for that UI element.
* Note that the create offer domain has a deeper scope in the application domain (TradeManager).
* That model is just responsible for the domain specific parts displayed needed in that UI element.
*/
class CreateOfferModel {
private static final Logger log = LoggerFactory.getLogger(CreateOfferModel.class);

View File

@ -42,17 +42,6 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.gui.util.BSFormatter.*;
import static javafx.beans.binding.Bindings.createStringBinding;
/**
* Presentation model:
* Knows Model, does not know the View (CodeBehind)
* <p>
* - Holds data and state of the View (formatting,...)
* - Receive user input via method calls from CodeBehind.
* - Validates input, applies business logic and converts input to Model.
* - Format model data to properties used for binding from the view (The view setup the bindings).
* - Listen to updates from Model via Bindings (The PM setup the bindings to the model).
* - Can be used for unit testing
*/
class CreateOfferPM {
private static final Logger log = LoggerFactory.getLogger(CreateOfferPM.class);