Presentation title
Download
Report
Transcript Presentation title
Design Patterns for MVVM
Unit Testing & Testability
Benjamin Day
Benjamin Day
• Consultant, Coach, Trainer
• Scrum.org Classes
Professional Scrum Developer (PSD)
Professional Scrum Foundations (PSF)
•
•
•
•
TechEd, VSLive, DevTeach, O’Reilly OSCON
Visual Studio Magazine, Redmond Developer News
Microsoft MVP for Visual Studio ALM
Team Foundation Server, TDD, Testing Best Practices,
Silverlight, Windows Azure
• http://blog.benday.com
• [email protected]
Agenda
• My assumptions
• Super-fast overview
Model-View-ViewModel (MVVM)
Unit testing
• How to build stuff and test stuff.
Assumptions
• Automated tests are required for “done”
• Unit tests are written by developers.
• QA testing is different from developer testing.
• MVVM in Silverlight is harder than WPF
(My demos will be in Silverlight.)
Design for testability?
• Way of architecting your application
• Easy to write & run automated tests
Things that need to be architected.
• Requirement: design for testability
• Requirement: testability in isolation
They call them unit tests for a reason.
Helps to remember Single Responsibility Principle (SRP)
• In Silverlight, figure out async first.
Not planning for async will crush SRP.
SOLID Principles of Class Design
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Principle
Purpose
Single Responsibility
Principle
A class should have one, and only one,
reason to change.
Open Closed Principle
You should be able to extend a class’s
behavior without modifying it.
Liskov Substitution
Principle
Derived classes must be substitutable for
their base classes.
Interface Segregation
Principle
Make fine grained interfaces that are client
specific.
Dependency Inversion
Principle
Depend on abstractions, not on
concretions.
Single Responsibility Principle
•
http://tinyurl.com/ahap3j
• Posters by
Derick Bailey
Things that need to be tested.
Goal: test your application without running the UI
• ComboBox / ListBox
Population of lists
Selection logic
• Field-based logic
Value, Visibility, Validation
Dependencies between
fields
• MessageBoxes
Alerts and exceptions
• ProgressBar logic
• Model to Data Access
• ViewModel to Model
Overview of unit testing.
What is a Unit Test?
• Piece of code that verifies that another piece of code
• Test code verifies application code
Why Write Unit Tests?
• High-quality code
Fewer bugs
Clean design
Clean code
• Professional Responsibility
Proof that your code works
Notification when your code is broken
Quality focus throughout the development cycle
• Side Effects
Code is easier to maintain, refactor
Self-documenting
Plan for testability?
•
•
•
•
If you build it, it needs to be tested.
If you can test it with an automated test, it’s better.
When you build, think of how to test it.
The architecture changes when you think about how to test.
• It is important to remember the
“Single Responsibility Principle”
So what is this MVVM thing?
Overview of MVVM.
What is MVVM?
•
•
•
•
Model-View-ViewModel
User interface interaction design pattern
Cousin of Model-View-Controller (MVC)
Enabled by data binding in WPF, Silverlight, WP7
Why use MVVM?
• …or MVC or MVP?
• Keep code organized
• Separate UI implementation from the logic
• Keep code out of the “code behind” (*.xaml.cs)
Hint: this enables Design for Testability
Our “To Do” list
• Architect the Silverlight Async solution
• Re-usable fields
Values, Visibility, and Validation
• List-based fields
ComboBox and ListBox
•
•
•
•
MessageBoxes
ProgressBars
ViewModel to Model
Model to Data Access
Tip: If you’re writing Silverlight,
figure out your async solution early.
Network traffic in Silverlight
• It has to be async.
• If it isn’t, the UI thread locks…forever.
My initial client-side architecture.
My architecture after Async WCF
beat me up and ate my lunch.
Async Kills
• Your Repository methods can’t return populated objects
must return void
• Exception handling is hard
Work happens on a different thread
Exceptions can’t “bubble up” the stack
• You could have your *.xaml.cs handle the callbacks
Ugly
Violates “separation of concerns”
Not very testable
Longer discussion of Silverlight async
• http://blog.benday.com/archive/2010/12/24/23300.aspx
Our “To Do” list
• Architect the Silverlight Async solution
• Re-usable fields
Values, Visibility, and Validation
• List-based fields
ComboBox and ListBox
•
•
•
•
MessageBoxes
ProgressBars
ViewModel to Model
Model to Data Access
Primitive Obsession in your ViewModel.
Primitive Obsession
• James Shore’s
“Primitive Obsession”
Too many plain scalar values
Phone number isn’t really just
a string
http://www.jamesshore.com/Blog/
• Validation in the get / set properties is ok but is phone
number validation really the responsibility of the Person
class?
Coarse-Grained vs. Fine-Grained
Object Model
• James Shore blog entry talks about Responsibilities
Fine-grained = More object-oriented
Data and properties are split into actual responsibilities
• I’m concerned about
Responsibilities
Code Duplication
Simplicity
ViewModelField<T>
• Provides common
functionality for a
property on a
ViewModel
With & Without ViewModelField<T>
Are your ViewModel properties
Coarse or Fine?
• Fine-grained gives you room to grow
• ViewModelField<T>
• Create custom controls that know how to talk to your
ViewModelFields
Simplified binding expressions
• Add features later
Field validation later
Security
Demo
VIEWMODELFIELD<T>
Demo
COMBOBOX & LISTBOX
Demo
MESSAGE BOXES
Demo
PROGRESS BARS
Our “To Do” list
• Architect the Silverlight Async solution
• Re-usable fields
Values, Visibility, and Validation
• List-based fields
ComboBox and ListBox
•
•
•
•
MessageBoxes
ProgressBars
ViewModel to Model
Model to Data Access
Focus your testing on stuff that
tends to be buggy.
Calls to data access are buggy.
• The goal: Data access should take/return Model objects.
• Databases
ADO.NET objects don’t look like your Model
Make the db call, convert the data to Models
Take the Model, convert it to a db call
• WCF Services
Service Reference classes *are not* your model
Make a WCF call, convert the data to Models
Take the Model, make a WCF call
• This stuff is always buggy.
Repository & Adapter Patterns
are your friend
What is Repository?
The Repository Pattern
• “Mediates between the domain and data mapping layers
using a collection-like interface for accessing domain
objects.”
http://martinfowler.com/eaaCatalog/repository.html
• Encapsulates the logic of getting things saved and retrieved
Synchronous Repository
Synchronous SQL Server & WCF
A Big Picture
What is Adapter?
Adapter Pattern
• “…converts the interface of a class into another interface
the clients expect. Adapter lets classes work together that
couldn’t otherwise because of incompatible interfaces.”
• from “Head First Design Patterns”
by Elisabeth & Eric Freeman
My version of Adapter Pattern
• Take object of Type A and convert it in to object of Type B
Why are these patterns your friend?
• Help focus your mind
• Better design
• Help contain bugs
These conversions to/from will be buggy
• Help localize change
Service endpoint designs will change often
• Unit test the conversions separately
(Remember it’s a “unit” test.)
Keep the Adapt separated from
the Retrieve
• Two classes
Repository knows how to talk to the WCF service
Adapter knows how to turn the Service Reference types into Models
• Single Responsibility Principle (SRP)
demo
REPOSITORY & ADAPTER
Our “To Do” list
• Architect the Silverlight Async solution
• Re-usable fields
Values, Visibility, and Validation
• List-based fields
ComboBox and ListBox
•
•
•
•
MessageBoxes
ProgressBars
ViewModel to Model
Model to Data Access
No shortcuts: Keep your ViewModels &
Models separate.
No shortcuts: Keep your ViewModels &
Models separate.
• It will be tempting to have your Repository/Adapter layer
create ViewModels
(Don’t.)
• There’s a reason why it’s called
Model-View-ViewModel
Why keep Model and ViewModel separated?
• ViewModel is a user interface design
• Model is the state of your application
aka. “Domain Model” pattern
• ViewModel advocates for the UI
1-to-1 between a ViewModel and a *.xaml file
Might reference multiple Models
• Don’t have the ViewModel fields directly update the Model.
It’s all about the Cancel button.
• If you’re “two way” data bound,
How do you undo?
Cancel: ViewModel wraps Model
• ViewModel populates
itself from the Model
• User edits the screen,
ViewModel gets updated
• Model doesn’t get changed until Save button is clicked.
• Model is The Boss.
demo
VIEWMODEL TO MODEL
ADAPTER
Summary: Our “To Do” list
• Architect the Silverlight Async solution
• Re-usable fields
Values, Visibility, and Validation
• List-based fields
ComboBox and ListBox
•
•
•
•
MessageBoxes
ProgressBars
ViewModel to Model
Model to Data Access
Thank you.
blog.benday.com | www.benday.com | [email protected]
Other Resources
• http://tinyurl.com/3d2soe8
Other Resources
• http://tinyurl.com/ln248h
Other Resources
• http://tinyurl.com/3pf8vxd