450 likes | 588 Views
MAX 2006 Flex Best Practices: Applying Design Patterns and Architecture. Joe Berkovitz Chief Architect, Allurent Inc. Resources and Updates. The latest version of this presentation and all sample code is available at: http://joeberkovitz.com/max2006/. Background.
E N D
MAX 2006 Flex Best Practices: Applying Design Patterns and Architecture Joe Berkovitz Chief Architect, Allurent Inc.
Resources and Updates • The latest version of this presentation and all sample code is available at: http://joeberkovitz.com/max2006/
Background • 25+ years developing user-facing software • Started in scientific data visualization and manipulation • Educational applications for K-6 • ATG: the web application explosion • contributor to Java Server Faces • currently Chief Architect at Allurent, Inc.
Overview • Why use architecture and patterns? • What we want from a "well-built" Flex application • A specific example: ReviewTube • MVCS: A useful division of labor in the client • Dealing with asynchronous communication • Guidelines and tips for view construction • Principles and recipes
What Is Software Architecture? • Ideas that give “mental traction” on building, understanding • Broad solutions to large problems • Themes that shape solutions to many small problems • Breaking up a complex system into simpler ones with… • responsibilities • relationships • interactions • Generating and characterizing diverse approaches • Comparing their concrete strengths and weaknesses
What Are Design Patterns? • Design Patterns are “mini-architectures” • Unitary, easily named (Command, Session Façade…) • Applicable to small, recurring problem spaces • Templates of responsibilities, relationships and interactions • Complex problems often map to a combination of patterns
What's a Framework? • A framework instantiates an architecture and set of patterns • Concrete software package with classes, APIs, etc. (e.g. Flex, Cairngorm, JSF) • Further nails down scope and nature of solution • Specific responsibilities, relationships and interactions • Implies set of possibilities and constraints • Gives you pros and cons; do you need the pros?
What We'd Like in a Flex Application • Isolate presentation, state, actions, communication • Cope with unpredictability of UI design, remote server • Parallelize design, client coding, server coding • Respond instantly to user actions, provide good feedback • Handle cross-cutting concerns: • testability • logging • security • error handling
Sample Flex Application • ReviewTube: a mashup between YouTube.com (a popular video publishing site) and a custom Comment Server • adds caption display synchronized with cue points in YouTube videos • YouTube provides metadata and media • custom Ruby on Rails server provides add-on caption data (and mirrors relevant metadata) Flex Client Views Controller Media Service Comment Service XML / HTTP YouTube Server Comment Server Metadata Media Captions
Flex Client Architecture: Models, Views, Controllers, Services interacts Views Models Session references interface notifies Login, Search… Video Browser Video Player Collection Controller VideoInfo Comment Services interface interface Comment Media Service Comment Service populates communicates
The Model: Representing State • Represents all client state as objects, collections, properties • All state changes dispatch events (and Bindable vars implicitly do this) • Does not refer to any non-Model application component Model notifies Session Collection VideoInfo Comment Comment
The View: Presentation and Interaction • Presents application state (the Model) to the user • Encapsulates all user interface design • Responds to user interaction by invoking Controller operations • Responds to Model change notifications by updating itself • typically MXML plus some fraction of AS interacts Views Model references Controller Login, Search… Video Browser Video Playback notifies
The Controller: Exposing Actions, Invoking Services • Encapsulates all user-initiated actions in the application • Modifies Model as needed • Invokes Services as needed • Manages indirect view-to-view relationships • acts as Façade for: • miscellaneous application logic • progress and error reporting • confirmation, validation • security and authentication Views interface Model Controller Services
The Service Layer: Remote Operations and Logic • Encapsulates all communication with the outside world • Populates Model objects with remote data • Logical place for stubs early in development or as test harness • Caching and other performance enhancements can be easily added Services Model interface interface populates Video Service Comment Service communicates
Code Break! • Let's look at a simple Model/View/Controller interaction
Interactions: Model, View, Controller, Service gesture Video Browser User initiates gesture, searching for videos by tag
Interactions: Model, View, Controller, Service getVideosByTag() Video Browser Controller View asks Controller to get the videos
Interactions: Model, View, Controller, Service getVideosByTag() Video Browser loadVideos(model) Controller interface Comment Service Controller uses Service to load videos into a model
Interactions: Model, View, Controller, Service getVideosByTag() model Video Browser loadVideos(model) Controller interface Comment Service Eager Model Creation: Controller returns model (still empty) to View
Interactions: Model, View, Controller, Service getVideosByTag() model Model Video Browser dataProvider Collection loadVideos(model) Controller interface Comment Service View binds Model as its dataProvider, listening for change events
Interactions: Model, View, Controller, Service Model Video Browser dataProvider Collection Controller VideoInfo VideoInfo interface … Comment Service server results communicates Service processes server response, populates model
Interactions: Model, View, Controller, Service updates Model Video Browser dataProvider binding changes Collection Controller VideoInfo VideoInfo interface … Comment Service Model emits event notifications, triggering View updates
MVCS In Summary • Model: semantic data only • View: interaction and presentation only • Controller: actions, mediation, cross-cutting concerns • Services: communication only
Approaches to Model Implementation • Value Object Classes: • vehicle for uniform data representation in client • All properties should be Bindable • All collections should implement ICollectionView or IList • Data only, no behavior allowed! • Ease of consumption by Views should usually drive design • Make data binding convenient!!! • Not identical to server representation • Minimize rearrangement of server data structures
The Asynchronous Tango: Services and Operations • Many operations require similar handling in the Controller: • they don't complete immediately • when complete, the results are used to populate Model objects • need status, progress, error reporting • Command pattern: Controller works with Operation objects which expose a uniform interface for completion, status, error handling, etc. • Factory pattern: Service can act as factory for Operations returned to caller; the Service properties (e.g. host URL, protocol, etc.) apply to all its Operations • Composite pattern: Operations can be composed into a higher-level CompoundOperation that executes its children in sequence
Interactions: Controller, Service, Operation Collection loadVideos(model) Controller interface Comment Service
Interactions: Controller, Service, Operation Video Query Operation Collection videos IOperation loadVideos(model) Controller new VideoQueryOperation(model) interface Comment Service
Interactions: Controller, Service, Operation Video Query Operation Collection videos IOperation loadVideos(model) Controller command interface Comment Service
Interactions: Controller, Service, Operation execute() Video Query Operation Collection videos IOperation loadVideos(model) Controller interface Comment Service
Interactions: Controller, Service, Operation Status Views activity status and progress execute() Video Query Operation Collection status events videos IOperation server results loadVideos(model) Controller VideoInfo … XML/HTTP request and response interface Comment Service
Interactions: Controller, Service, Operation execute() Video Query Operation Collection completion event videos IOperation loadVideos(model) Controller VideoInfo … interface Comment Service
Sample Controller Code from Controller.as: public function getAllVideos():ICollectionView { var data:ArrayCollection = new ArrayCollection(); performOperation(commentService.loadAllVideos(data)); return dataProvider; } public function logout():void { performOperation(commentService.logout()); } public function performOperation(op:Operation):void { showStatusText(op.displayName); op.addEventListener(Event.COMPLETE, operationComplete); op.addEventListener(ErrorEvent.ERROR, operationFailed); }
Sample Service Code CommentService.as: public function loadAllVideos (dataProvider:ArrayCollection):Operation { return VideoQueryOperation.allVideos(this, dataProvider); } VideoQueryOperation.as: public var videos:ArrayCollection; public static function allVideos // static factory method (s:CommentService, dp:ArrayCollection): void { var c:VideoQueryOperation = new VideoQueryOperation (service.urlPrefix + "/all"); c.videos = dataProvider; return c; }
Approaches to View Implementation: The Fundamentals • If you don't code to enable reuse, it won't happen! • Set child properties to communicate "inward". Avoid using functions; you can't use data bindings with them • Dispatch events or set Bindable properties to communicate "outward" (code example: VideoTimeStrip) • Components shouldn't know what type container they go in • Containers shouldn't know what's inside their children • Temptation: MXML id-based properties are always public! • Refactor ruthlessly
Approaches to View Implementation Use inheritance to separate view logic (ActionScript)from layout and styling (MXML) • Examples: LoginPopup, RegistrationPopup • Superclass in ActionScript; specifies common properties and function definitions • Superclass public var x:Componentmay be overridden in subclass by <Component id="x"/>.
Approaches to View Implementation Childless MXML components A "childless" MXML superclass can customize superclass properties and be used as a component itself in some other MXML file (with optional children). For example, SmallCanvas.mxml might contain simply: <mx:Canvas mx:width="32" height="32"/> Some other component can then use: <SmallCanvas> <SomeChildComponent/></SmallCanvas>
Cool Binding Patterns If you want a property change to have some kind of side effect in your component, bind to a setter function that does the work. example: YouTubeVideoDisplay requests URL when video property changes You can bind a function of a Bindable: <mx:Label label="{DateTimeUtils.formatOffset(time)}"/> You can bind an expression with multiple Bindable inputs; it will be reapplied if any input changes. <mx:Button enabled="{canRegister(password.text,repeatPassword.text)}"/> Factor out expressions like that, by binding to a local Bindable: [Bindable]var registrationOK:Boolean;<mx:Binding source="canRegister(password.text,repeatPassword.text)}" destination="registrationOK"/>
Miscellaneous Tips Never assume properties will be set in a well-defined order • Bindings can fire in an unpredictable, indeterminate sequence • Example: CommentCaption's treatment of comment, videoOffset All event handling functions should be private Isolate style/skin knowledge: always prefer styleName to explicit styles
The Cairngorm Framework • It's well conceived and executed • Many people like it • It handles many of the issues discussed here • Some differences: usage of Command, Responder, Locator patterns • Semi-aligned with concepts in J2EE Core Patterns • Strong reliance on event broadcasting for user actions
Avoiding The Dark Side • Preconceived vs. emergent approaches • Force-fitting problems to patterns:“If I have a hammer, this must be a nail” • Using patterns needlessly:“That looks like a nail, I must need a hammer” • Satisfy key needs, not possible needs • Abstraction costs time: use it at obvious “hinge points”
The Land of Many Right Answers • There's always more than one way to do something • Business and politics do influence technical approaches, like it or not • Patterns and practices in the end are a tool to meet one's real-world needs
Resources • Sample code, updates to presentation can be found at: http://joeberkovitz.com/max2006/