Transcript of "Maximizing Code Reuse Across Screens"
MAXIMIZING CODE REUSE ACROSS SCREENS Flash Builder 4.5 and Flex SDK 4.5 (including mobile Flex) 1Hello, and welcome to Maximizing Code Reuse Across Screens. This is the part of the talkwhere I am a bit nervous. But don’t worry, it goes away in a few slides :).
Your Presenter • Jason Hanson • twitter @jayfour000 • ﬂexfood.blogspot.com • www.jasonhanson.com • Building for Flash Platform since 1999 • Working with Hero SDK since Aug, 2010 (beta) 2My name is Jason Hanson. If you are interested in learning more about me, what I do, or have questions after this presentation please feel freecontact me via Twitter, my blog, or web site.A little about me. I have been building for the Flash Platform since 1999, back when I used FlashScript and really had no idea what I was doing.I have stuck with the platform for the past 10+ years, started working with Flex Builder 2 when the beta came ou and have been buildingprojects with Hero since August of 2010.
Stuff to check out if you get bored • http://www.jasonhanson.com/360ﬂex 3I have slides, sample code, and some AIR for Android APK ﬁles hosted up on my website.Please feel free to check it out at any time.
So many screens So little time • Desktop • Laptop • Phone • Tablet • TV • Car Dashboard • Fridge, windows, clothing, coffee table 5So many screens, so little time. As we all know the devices and places that humans are using softwareapplications is blowing up. Every few weeks it seems a new hardware device, or software platform comesout. As a software developer I need to go to where my users are at, and many of them are not on a desktopcomputer. Many don’t even own a traditional computer.
LOCATION, Location, location • Take your business to your users • Your business stays the same • Your apps need to change based on how the user interactions with the screen of their choosing • Your business should seamlessly ﬂow between screens 7Your software application is more then just an app. It may be software as a service that connects to a super-fancy backend, or it may a gamethat is part of it’s own platform independent brand. Anyone here think that is is annoying that Instagram does not work on Android? OrAngryBirds on Blackberry? In my experience, most Users don’t care about platforms, devices and OS, they just want to use the software theylike on whatever screen they have in front of them. Some do this well. Kindle syncs my position between my iPad and Android phone when Iopen a book. Hulu and Netﬂix remembers what I was watching when I walk from my Laptop to my TV and I pick right up. The experience ofthe software platform is seamless. Many of the core features of the software platform are the same, just consumed and presented differently.
Drink the Kool-Aid? 8If you are here you have likely at least tasted the Kool-Aid that is the Open Screen Projecteven if you have not hooked it up to an IV yet.
Flash Platform Offers One Option • Write core business code once • Reuse on each new screen target • Build custom views appropriate for each screen target • Modify core code as needed for special cases 9Flash platform offers one option to take your software application to many screens. Other talks at thisconference will go into great detail about the hows and whys, and ins and outs of each target screen thatFlash and Flex supports. This talk will cover a way to get the most of out your code when targetingmultiple screens.
Code Reuse with Flash Builder 4.5 core test lib runner iOS view view Web lib lib AIR for Android AIR for * Desktop 11Project Organization: Presently I am going to cover a way to organize your project that supports sharing code between multiple screens. Thecode is housed in multiple Flash Builder 4.5 created projects. The starting point is a Flex Library Project I like to call “core lib”. After that I willcreate several screen target projects for Web, Android, iOS, AIR, etc. Sometimes I may end up creating some view component what will workacross multiple screen targets (like desktop AIR and browser Web). I make a Flex Library Project for those shared components. And lets notforgot testing! A test runner project can be created for running tests on all the “core lib” code, if you are into that type of thing.
core lib core lib • Business Logic • .model • .controller • .presenter • .service • .event • No view code 13Let’s start with the core lib. This is the where all your business logic code goes. Themodels, controller, presenters, utils, service code, complex algorithms, etc. Any code thatis a core part of the business logic is a good candidate to put into this library.
core lib core lib • Flex Library Project • Remove “view” libs from Library path • Keep framework.swc for data classes like ArrayCollection and BindingUtils • Keep rpc.swc for HTTPService and AsyncToken 14The core lib should be a Flex Library Project. It will compile into a SWC ﬁle, not a SWF ﬁle. A good practice is to remove all the “view” libs fromthe Library Path. This will keep you and your team for inadvertently including code that will bloat the library. No Spark code goes into this lib,so it is likely that you could build it to be compatible with Flex 3 project in addition to 4 and 4.5. Be sure to keep framework.swc and rpc.swcfor some super-helpful and relatively light-weight classes like ArrayCollection, BindingUtils, and service code.
test runner Test Runner • Flex Project • FlexUnit 4 built into FlashBuilder • You can build out most of the core lib with only unit tests • Mock services 16Make a test runner project. This can be a Web or AIR project. I like to use the FlexUnit 4 integration that is built into Flash Builder. Write testsfor everything in core lib. Important to make this lib bullet-proof since it is going to be used in multiple projects in varying ways. Put yourengineering efforts into writing good tests. I ﬁnd that I can build out the majority of the business logic of an application without writing asingle view class, just unit test and integration test against core lib. If you want to learn more about writing unit tests you are in the write placethis week. Everything I learned about writing unit test was from people who are hear at this conference :).
Screen Targets • Web (.swf) • AIR (.air) • AIR for Android (.apk) • iOS (.ipa) • AIR for BlackBerry Playbook (.bar) • AIR for * (.***) 17The view code is often not shared between screen targets. The way that a user interacts with the user interface is often very differentbetween web and mobile, and other screens. Make a new Flex project for each type of screen target you want you app to run on. You willneed to compile each of the screen target applications separately.
18Flash Builder 4.5 supports some new project types. Here is the list of project types tochoose from.
Tips for AS3 Projects 20A tip for AS3 only screen target projects. When setting up the project be sure to add in framework.swc and rpc.swc to accommodate anyproperties marked as [Bindable] in the core lib and for the HTTP service communication classes.
Tips for AS3 Projects 21Hot tip; to get around the issues with resource bundles required by framework.swc for locales you can modify the compiler argument for -locale to read “-locale=”.
22Now that we have covered a bit of the project organization I am going to go over a project architecture thatworks well for me when targeting multiple screens.
Architecture • MVC (with presenters) i es controller e rt r op p method • Model re calls o event st • View • Presenter model presenter event • Controller method calls • Passive view view view view view view 23The architecture that I found works well for sharing code across multiple screen is a version of MVC withthe addition of presenters. The biggest departure from MVC or MVP is that the views and presenters do notcommunicate with the models, only the controller does. This is to reduce tight-coupling between the viewobjects and other part of the application.
presenter Presenter • Same basic concept as Presentation Model • Separates business logic from view • Views change more frequently then any other part of the app • Views for different screen targets may have vastly different display code 24Using presenters or presentation models promotes developers to separate application logic from display logic. There is no automated way to‘enforce’ good encapsulation practices, however the presence of presenters in a separate code project provides a good ‘rule of thumb’ checkfor where application should go. If you see lots of non-display code in a view ﬁle chances are that some of it should move to a presenter.
presenter Presenter • Public methods to do ‘stuff’ • Contract exposed with interface • Communicates by dispatching events • Dispatches events to controller • Dispatches events to views • Never holds instance of views 25Presenters expose public methods, ideally via an interface, that can be called by views. Presenters also expose public setters that can be calledby the controller or views. A presenter should have no knowledge of any methods or properties in the controller, nor know about any viewclasses. Dispatches events as the only form of communication with other parts of the application.
presenter Presenter • Why Bother? • Same presenter can be used for multiple views in multiple screen target apps • Code in presenters can be unit tested, while code in views is often very hard to test 26So why bother with presenters? Adobe put in that MXML <script> tag for something, right?Seriously though business logic in views is just a bad idea. It makes your project harder torefactor, harder to test, more brittle, and much harder to share code between multiplescreens.
controller Controller • Control messaging (Grand Central) • Manage state • Listen for events from presenters • Make service calls • Set properties on presenters • Set properties on the models 27
model Model • Hold instances of top-level presenters • Sparingly hold instances of data shared between multiple presenters • Singleton • Easy to ‘inject’ into views • Only place a singleton is used • Not an IEventDispatcher 28
view view view view view View • Never in core lib • Screen speciﬁc display code • Holds instance of presenter (interface) • Makes function calls on presenter • Listens to events on presenter • Holds little or no data 29Views change often. Views on each screen target call for a speciﬁc implementation depending on how the user interacts with the screen. Thereis not much sharing of view code between screens. The views are dumb. All the logic is in the presenters. All the state is held in thepresenters. Reusing the presenters for multiple views is where the power of this approach to development really starts to pay off. Rememberthat the presenters are in the core package that is completely unit testable. Adding a new screen target allows you to use the same presentersyou have already tested in other application targets.
view view view view view View 30AS3 view close for a log in screen. Notice the call to presenter.login()
view view view view view View 31MXML code for a login screen. Notice the call to presenter.login()
view view Screen view view view Targets • View code is “throw-away” code • Resist the urge to over-engineer views • Often faster to just rewrite view code then it is to 32NextSlide
view view Screen view view view Targets 33Too many times I have over-engineered a view class trying to anticipate n number different conﬁgurations only to have the design changedrastically in the next sprint. Then I make a really bad decision. Since I am attached to the technically-sexy view component I wrote I try andmodify it to work with the new design and end up spending 2x longer on it then if I had just started from scratch.
Application State • Application state per functional area • Presenter for each application state • Presenter to view ratio may not be 1:1 • Some views may reuse the same presenter 36Define application state by functional area, not necessarily by view. Build a presenter for each application state. Depending on yourscreen target, the number views and application states often will not have a 1:1 relationship. For instance, on web a login featuremay only be 1 page with multiple Spark states, however on mobile a complete login feature would likely be multiple pages (entercredentials, forgot password, register new user, etc.). I find that I often reuse presenters in multiple views on mobile.
Application State • Presenter currentState property • For MXML view bind the presenter.currentState to the currentState of the view • Change state on the presenter changes state on the view • In most cases views and presenters do not modify currentState, the controller does 37Most of my presenters get a currentState property that is used to hold the state for the view.When building MXML views I bind the currentState to a property in the presenter. When thepresenter’s currentState property is set the view is listening and will change state. Likemagic./bow *All power to the almighty controller*
Application State 38example of binding to currentState
Tip: No States as a String-Based Contracts • Bad idea in general • Typos break apps at runtime :( • Use enums or constants for state names • Spark state name property does not support constants values. Must use a string in this case. 39State values should be constants. In absence of an official enum primitive in AS3 a list of constants will work. I strongly adviseagainst using string-based contracts where the strings are not set to constant values. I have spent weeks, if not months, of time inover the last ten years tracking down bugs related to typos in string-based contracts.
Spark States User error failure point. Strings not compile checked against enum. 41Point of failure due to user typo. During beta there were some silent runtime errors causedby setting currentState to an unknown value that motivated me to write a state validator.
State Enum 42If you could not tell by now, I have some personal issues with string-based contracts ...probably a dyslexia thing.
ViewNavigator State Translator• Mobile View-Based Applications use a ViewNavigator • Similar to a stack of cards • pushView(viewClass:Class, ....) • popView() • popToFirstView() • not state friendly by default 43
ViewNavigator State Translator• ViewNavigator methods require a view class type• State is held in the ‘core’ presenters• Presenters have no knowledge of screen-speciﬁc view classes• Need to translate states to view classes 44