Design Patterns in ZK: Java MVVM as Model-View-Binder

Embed Size (px)

Citation preview

Presentation Patterns In ZKSimon Massey(Revised Q2 2012)

Introduction

First version of this presentation was given to the 2010 UK ZK Users Group

The "ZK ToDo 2" patterns sample code is in the zktodo2 repository at github.com

Sample code has the same screen implimented three times; as MVP, MVC and MVVM (MVB)

Published articles document the MVP and MVC versions. Article coming soon about MVVM...

See references at the end

Overview

Why Patterns?

Patterns recap of View and Model

Model, View, Who? The third part

Best practices for each layer

Why Patterns? Evolving Software

A business sponsor talks about the screens but requires a flexible business solution

Screens are likely to change all the way through to go-live and well beyond

Features evolve slowly over time whilst the screens can change drastically

Can you easily reskin / re-layout / rearrange your app to freshen your user experience?

Making flexible and adaptable solutions is more rewarding than making brittle apps

Why Patterns? A Challenge!

Reuse a "buy now" feature of your website in an iphone app (as XML over HTTP)

This requires separation of View from Model

Programming In The View

MyDao myDao = ; // get dao via jndi myDao.buyBook(user.id, hiddenBookId.value);statusLabel.value = Thanks! Buy another book?;]]>

Business state stored in viewView knows 'who' and 'how'Update and render mixedReuse?Cut & Paste Job!

Avoid Coding In The View

"Separated Presentation is a core pattern

Presentation is incidental to what the customer is logically doing which is the Use Case / User Story (e.g. "customer buys book")

The presentation changes fast and often so separate it out from the business logic

Junit testing of the presentation is tricky

Business logic within the View stunts the flexibility of your software design

The Triumvirate

ViewModelwho?

Micro vs. Macro

Much of the literature about MVC describes the fine grained "micro-MVC" used to implement graphical components such as Swing/JSF

When reading articles it helps to think "Is this micro-MVC or macro-MVC?"

This century we tend to pick a winning UI component framework (ZK!) and focus on "macro-MVC" for complex business screens

This presentation talks about the macro world unless explicitly stated

The View

ViewModelwho?

View Best Practices

"ZK Desktop == View" so mixing Java business logic into ZK code is mixing business logic into the View

View components should not become business components:BuyNowButton extends Button // avoid!

The View should observe the Model using the databinder (more on this later)

View Has Micro Models

A BindingModel is an "push through" to update the View. Writing to it updates the bound View

These micro models are not business domain models which organise application features

ListModelList is binding model class for ListboxlistModelList = (ListModelList)listbox.getModel();

AnnotateDataBinder uses such micro-models as part of its logic to sync data into the View

Intbox and Datebox have "value" property as micro-Model as well as "visible" and "disabled"

ZK Micro-Model == View

ListboxListModelListComposer

Collection books

(view layer)

(business domain layer)

The Business Domain (Macro) Model

ViewModelwho?

Model Best Practices

The Business Domain Model should have no compile time dependencies to the presentation framework

EL and DataBinder should load data from the Model into the View (avoid coding)

Ideally the Model should be a rich Domain Model have both behaviour as well as state

Beware designs of proceedural code loading and saving DTOs as this is weak OO

Try test driven development of encapsulated layers ("POJOs In Action" book)

The Other Bit...

ViewModelwho?

Alphabet Soup

MVC: Model-View-ControllerOften cited but do we really know it as well as we believe?

MVP: Model-View-PresenterA specialism of MVC with a dominant controller

MVVM: Model-View-ViewModelThe Microsoft WPF pattern of the Application Model but how do we use it with ZK?

MVB: Model-View-BinderA clearer moniker for "MVVM" with ZK

MVC Has Many Interpretations

Martin Fowler: Different people reading about MVC in different places take different ideas from it and describe these as 'MVC'.

Anon on c2.com:Stuff nearest the User becomes the View, stuff nearest the database becomes the Model, stuff in between becomes the Controller. Marketects then refer to their project's architecture as "MVC", borrowing that acronym's impressive lineage(!!!)

Controller Of What?

ViewModelController

?

?

?

The Controller Revisited

Typically org.zkoss.zk.ui.util.Composer but what are it's responsibilities?

Does Controller read/write the Model? Yes

Does Controller read/write the View? Perhaps

Does View read/write the Model? Possibly

Is separation of behaviour (Controller) from state (Model) the only game in town? No

Is databinding with AnnotateDataBinder part View, part Controller, or a separate thing?

Model-View-ZKComposer

org.zkoss.zk.ui.util.Composer usually used as the 3rd part of the pattern

Whether it is a Controller or a Presenter depends on the interactions with View and Model:Presenter pushes to Passive View

Controller updates a model observed by the View ("Supervising Controller")

Any mix or match of the above will be called MVC. People say "traditional MVC" to mean View observes the Model updated by Controller

Model-View-Presenter

ViewModelPresenter

compiles to

Legend

events

Model-View-Presenter

The View is the fully owned by the PresenterZkToDoControllerV1 implements Composer

Pushes all updates into the Passive ViewZkToDoControllerV1 implements ListitemRender

Presenter reacts to View Event notifications and updates the Model

ZkToDo2 app example zktodo2_a.zul

For code write-up google "Massey Small Talks/2008/November/ZK "

Model-View-Controller

ViewModelController

Legend

compiles to

bindings

events

Enter The Binder

View observes the state of the Model using databinding

Uses EL annotations within the ZUL page

The @{pojo.property} annotations automatically reads/write your POJOs (no UI event handling code required as ZK Binder does the work automatically!)

Controller Best Practices

Aim to have the Controller and View not communicate with one another. Let the binder to the work

Have the binder pull the data from the Model with load hints rather than having the composer push data into the view model

zktodo2_b.zul example should have used more 'load-after' hints and less Java code

Model-View-ViewModel

ViewModel (Microsoft) is similar to an ApplicationModel (Smalltalk)

Binder syncs application state into the View

Binder maps View Events onto application methods (ICommand types in .Net C#)

Gather both state and behaviour into one application model (stronger OO design)

Binder is part of the View world. The application model is its model: so called it a "ViewModel"

ViewModel Nirvna

Josh Smith (msdn.microsoft.com):"ViewModel classes are easy to unit test Views and unit tests are just two different types of ViewModel consumers" "ViewModel classes can assist in properly designing user interfaces that are easy to skin""It is easy to just rip one view out and drop in a new view to render a ViewModel"

It's all about the Binder. The name Model-View-Binder (MVB) highlights the key part

Model-View-Binder

Legend

compiles to

command

load

View

BinderViewModel

DomainModel

Model-View-Binder (Simplified)

Legend

compiles to

updates

ViewBinderApplication Model(has internal layers)

loads

Model-View-ZKBind

Components are bound to ViewModel by the Binder:

UI Events are dispatched to ViewModel methods by the Binder:

ViewModel has annotations to inform Binder of any properties changed under the covers

@NotifyChange({"reminders","selectedReminder"}) public void save() { }

MVB/MVVM Best Practices

View Model has no references to View Objects only @Command and @NotifyChange annotations

Create ViewModel classes which are "naked screens" onto which you overlay a zul skin

ViewModel is the Mediator of the Binder to the Model; it orchestrates the services

Use Dependency Injection of service interfaces into the View Mode

ViewModel uses application services to get detached entites which it exposes to the Binder

ViewModel Choices

Is ViewModel a Mediator to your Model? Is their lots of plumbing to access your services?

Whether you "pull" through your ViewModel "push" through Controller to BindModel is key choice

My vote is to first attempt a strong ViewModel with no Controller (but do what works for you)

ZK6 has GlobalEvents concept so that Controllers can notify ViewModel

Nested ViewModels? Mix and match? Why not?

Summary

Presentation patterns are all about modelling the features of our application independently of the frequently changing screens

MVC, MVP, MVVM all have in common a separated view

Modelling of the Model will lead to internal layers

Labels such as "ViewModel" or "DataModel" or "ApplicationModel" are suggestions as to what is trying to be organised where

Summary (Cont 1)

"B" is for Binder which plays a part in MVC "Supervising Controller" and major part of MVVM "Presentation Model" patterns. There is no "B" required for MVP "Passive View" pattern

The Microsoft Binder is powerful and a core part of their framework. They promote MVVM as the best practice to organise a screen Model to leverage their Binder

MVB is a moniker that names the new power in modern Separated View patterns: long live the Binder!

Summary (Cont 2)

ZK has DataBinder for rendering POJO data values and state (visible/disabled) into ZK AJAX RIA Desktop Components

ZK6 adds CommandBinder to fire application methods on the ViewModel

The binding information is embedded into the Page (View) as "XML annotations"

ViewModel has no compile time dependencies on ZK Components; can heavily junit with mock services

Using MVVM / MVB pattern is simply about getting the most out of the framework Binder

References

MVC article Desktop MVC Patterns ZK, Spring & JPA

Original MVP article SmallTalks 2008 Best MVC Patterns

Book on how to build a layered domain model with Spring POJOs In Action

ZK MVC Screen for POJOs In Action book code Test Driving ZK FoodToGo

Book on designing domain objects first for supple code Evans Domain Driven Design

Martin Fowler GUI Patterns pages UI Architectures

Josh Smith's inspirational Microsoft .Net MVVM Article

Corrections

March 2012: Slide 13 had totally miss attributed Fowler where I was using the term "Presentation Model" to mean something totally different. Edited to call my concept "BindingModel"

March 2012: Slide 21 had crossed the wires on Passive View and Supervising Controller

Muokkaa otsikon tekstimuotoa napsauttamalla

Muokkaa jsennyksen tekstimuotoa napsauttamallaToinen jsennystasoKolmas jsennystasoNeljs jsennystasoViides jsennystasoKuudes jsennystasoSeitsems jsennystasoKahdeksas jsennystasoYhdekss jsennystaso