foomonger's blog

Tips and Musings on Software Development, Flash, and Flex

foomonger-swizframework Updated With Swiz v1.0.0 and AS3Signals v0.8

without comments

You can find the source, SWC, and examples here: http://code.google.com/p/foomonger-swizframework/

Thanks to the Swiz Framework team and Robert Penner for delivering free useful code!

Share

Written by Sam Ahn

January 5th, 2011 at 12:53 pm

Posted in Uncategorized

Tagged with , ,

Lessons Learned in Agile

without comments

I've been using Agile software development methodologies on a variety of teams over the past few years, often playing the ScrumMaster in addition to a full-time developer. In this post I'll describe notable lessons I've learned.

Planning Meetings

I don't know anyone that enjoys 8 hour planning meetings. I used to find them useful for getting the entire team on the same page but it's painful. Now I prefer something more scrum-ban style and hold weekly 30-45 minute planning sessions. Just enough to fill out the backlog for a week or so.

Reality Check

Agile doesn't alter reality. I think it just helps expose it. In the end some of the variables you have to work with are still the same: people, time, and scope. If your product owner sends out an email telling the team to work harder to hit a deadline because scope is no longer negotiable ... reality check. If you uncover some technical debt that makes what you thought would take about a day to take more than a week ... reality check. At each hurdle I've encountered I make sure to take a step back, unemotionally embrace reality, looks at my choices, and then more forward.

Fine-grained or Coarse-grained User Stories

Having gone both extremes when fleshing out a backlog I now lean towards coarser-grained user stories. I found that while finer-grained stories help expose what's exactly being worked on, it's at the cost of a cluttered backlog which makes it more difficult to determine the progress of overall business value. The downside of coarser-grained stories is that tickets may hang around longer than you'd like and look stagnant. I think it's an art and I find that regular communication through daily scrums and team chat rooms helps keep an eye on detailed progress.

Defining "Done"

I used to think I was cool wanting a firm and awesome definition of "Done" for a user-story. Code complete, design reviewed, unit-tested, QA'd, etc. Don't get me wrong, I still like the idea of Done. In a recent project we didn't have UI designs for a while. I defined Done to include design of course. But after a while the design bottleneck caused the list of in-progress tickets to grew unbearably. Tickets were code-complete and QA'd, but the designs just weren't applied yet. It was difficult to quickly see how the team was doing. I later decided to remove the design requirement for Done and created separate chore tickets (in Pivotal Tracker) to address designs later. When design was no longer a bottleneck, it was added back as a Done requirement. It wasn't perfect but in that situation my desire to improve flow and process trumped my desire to have concise and perfectly Done tickets.

I can't claim these lessons as absolute fact, but I hope someone fines them helpful. Happy Agiling.

Share

Written by Sam Ahn

September 17th, 2010 at 12:46 pm

foomonger-swizframework Updated With Swiz 1.0.0 RC1

with 2 comments

Swiz 1.0.0 RC1 was recently released so I've updated my custom metadata processors to work with it. Head over to Google Code to check out [MediateSignal] and [Resource]. Happy coding...

Share

Written by Sam Ahn

May 23rd, 2010 at 2:26 am

SwizLogger Helpers: SwizLoggerConfig and LoggerProcessor

with 2 comments

I started using the SwizLogger recently and quickly realized I wanted to do the following:

  1. Create ILogger instances without importing Swiz classes in my application classes
  2. Easily add targets in MXML

#1 isn't a huge deal if you consider logging to be more of a system tool than an application dependency, but if I'm avoiding Singletons why not keep it up. #2 also isn't a big deal because it doesn't take much ActionScript to add logging targets, but I think it makes a lot of sense to do it declaratively.

Piotr Walczyszyn created a custom LogProcessor to address #1, but I didn't like how the TraceTarget was hard-coded into it. Instead of building more complex processor I decided to create a bare-bones LoggerProcessor and SwizLoggerConfig class.

Here's an example application's source (the SWF is just a button):  Source

The LoggerProcessor is again bare-bones. All it does is inject an ILogger instance using SwizLogger:

[Logger]
public var logger:ILogger;



The LoggerProcessor priority is set to be one above [Inject] so the injected ILoggers are available at [Inject] and [PostConstruct].

SwizLoggerConfig doesn't do too much either. It's just provides a default public Array property which is used to add targets to the SwizLogger.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        xmlns:utils="com.foomonger.swizframework.utils.*"
        xmlns:view="example.view.*"
        xmlns:local="*"
        layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.logging.LogEventLevel;
        ]]>
    </mx:Script>
    <utils:SwizLoggerConfig>
        <mx:TraceTarget
                includeCategory="true"
                includeDate="false"
                includeLevel="true"
                includeTime="true"
                level="{LogEventLevel.INFO}"
                filters="*"
                fieldSeparator=" | "/>
    </utils:SwizLoggerConfig>
    <local:SwizLoggerConfigExampleSwiz/>
    <view:MainView/>
</mx:Application>
 


The value of these classes will depend on your personal style and preference. I wrote them so I like them. They're available on Google Code.

Happy coding.



* Update: Here's the MXML syntax for adding multiple packages to the filters Array:

<mx:TraceTarget
        includeCategory="true"
        includeDate="false"
        includeLevel="true"
        includeTime="true"
        level="{LogEventLevel.INFO}"
        fieldSeparator=" | ">
    <mx:filters>
        ["foo.bar.*", "com.foomonger.*"]
    </mx:filters>
</mx:TraceTarget>
 
Share

Written by Sam Ahn

March 20th, 2010 at 6:46 pm

Posted in flash, flex

Tagged with , , ,

Swiz, ResourceManager, and [Resource]

with one comment

I'm using the Swiz Framework in a side project which requires runtime loading of all the copy. I decided to use Flex's ResourceManager by parsing static XML files and populating the ResourceManager with the newly created ResourceBundles. Binding resources into view's wasn't too bad, but it could be better. For one thing any component that needed a resource included a ResourceManager dependency. So I thought about it and then created a ResourceProcessor which really cleans things up.

Here's an example application:

I set up the [Resource] tag to mirror the @Resource directive. All you do is decorate a property like so:

[Resource(key="title", bundle="example")]
[Bindable]
public var title:String;

The processor binds the resources so they will update when binding events fire in the ResourceManager. And you only need to include a ResourceManager dependency if you are adding resources at runtime or changing the locales array.

This processor is available in my foomonger-swizframework project on Google Code. Enjoy!

Share

Written by Sam Ahn

March 10th, 2010 at 1:48 am

Posted in flex

Tagged with , , ,

Swiz, Signals, and [MediateSignal]

with 2 comments

Joel Hooks created this RobotLegs/Signals demo. Ben Clinkinbeard then created this Swiz-version of Joel's demo. I then took Ben's demo and Swiz-ified it even more by using a custom [MediateSignal] processor. Here's the source.

[MediateSignal] is the Signal equivalent of [Mediate]. Here's an example:

[MediateSignal("galleryUpdatedSignal")]
public function galleryUpdated(gallery:Gallery):void

[MediateSignal] takes a Signal Bean name or type and adds the decorated method to the Signal (see GalleryThumbnailsPresentationModel for examples).

This is what I changed from Ben's demo:

  • Created the MediateSignalProcessor
  • Added [MediateSignal] metadata to the Signal listeners
  • Made the Signal listeners public
  • Named the Signal Beans
  • Removed [PostConstruct] methods that added the Signal listeners
  • Removed injected Signals that weren't being using to dispatch

[MediateSignal] makes using Signals in Swiz very parallel to using Events (especially if you define the Event dispatcher as a Bean and inject it by name). And just like Events, you only need to [Inject] the Signals into Beans who are dispatching Signals. I was pretty excited to create my first custom processor and play with Signals for the first time. Let me know what you think!

Disclaimer: I set up MediateSignalProcessor to also handle DeluxeSignals and remove listeners, though to be honest I didn't test those.

* Update: I've posted the processor on Google Code and it contains unit tests (including DeluxeSignals and removing listeners).

** Update: I've created a bare-bones example application: SWF and Source.

Share

Written by Sam Ahn

February 26th, 2010 at 11:37 pm

Posted in flex

Tagged with , , ,

Testable-Driven Development

without comments

Test-driven development. Tried it. Sometimes loved it. Rest of the time hated it.

I think TDD is great when you know what the code should do. When I'm writing parsing code or something else very utilitarian I definitely prefer to write the tests first. As a Flex/Flash developer, most of my code is directly for the UI, and often I find that I'm not entirely sure what my code should do right away. I'm becoming a big fan of the Presentation Model pattern, but even with that, I find that it takes exploratory development to determine exactly which component should do what and which logic should go where.  I found it very burdensome to update both the regular code and tests step-by-step . Not being a TDD expert I could easily be doing something or interpreting something incorrectly. Or perhaps I'm just lazy.

I've decided, at least when it comes to UI development, to follow a looser Testable-driven development technique. As I'm fleshing out my component logic, I constantly ask myself, "Is this code testable?" or more generally "How will I know if this works?" This primitive technique gives me the freedom to write exploratory code while helping to reign in potential magic logic. I then write tests once things have settled down, refactoring any logic to make things more testable as necessary. This technique also fits my style of coding where I like to sketch out logic with small tracer bullets.  It definitely takes some discipline to think about the testability of the code, but so far I'm much more comfortable with testable-driven development for UI work.

Share

Written by Sam Ahn

February 23rd, 2010 at 10:53 am

Mocking Loader and Services

with 2 comments

I've been using mock-as3 in my Flex unit tests a lot recently discovered a couple useful strategies for mocking things that are not obviously mockable at first glance:  Loader and Services (AsyncToken).

Here is the source for a Flex project that I'll be referencing that contains a sample controller with its tests: MockingLoaderAndServices

Most of the relevant code is in com.foomonger.blog.mockingloaderandservices.controller.ControllerTest.

ControllerTest contains tests for Controller which has 2 methods: loadAssetsSwf() and loadDataXml(). Those methods call corresponding methods in the Delegate. loadAssetsSwf() demonstrates loading a SWF using a Loader. loadDataXML() demonstrates loading XML through an HTTPService. In ControllerTest I create MockDelegates which is then injected into the Controllers.

flash.display.Loader

When loading a SWF into another SWf, you use the Loader class and listen for events from the contentLoaderInfo property. To mock the loading of a SWF, you have to simulate events being dispatched from contentLoaderInfo. The problem is that you can't call dispatchEvent() nor subclass LoaderInfo and instantiate it.

The solution: LoaderInfo2. In the source you'll see that the class flash.display.Loader2  subclasses Loader and adds a contentLoaderInfo2 property of type IEventDispatcher. By default it's set to the normal contentLoaderInfo, but can be set to a generic EventDispatcher for testing. When you set contentInfoLoader2 to an EventDispatcher instance, you can then call dispatchEvent() on it. Note that Loader2 is used instead of Loader in the Delegate and Controller. See ControllerTest.test_loadAssetsSwf_complete() .

This is not an ideal solution but works well enough for my uses.

mx.rpc.AsyncToken

When loading data using Flex service objects, you get back an AsyncToken which you can add event listeners and responders. I typically add responders. To mock the service calls, you have to simulate the calling of the responders. The problem is how do you trigger the response?

After a little digging around, I found that ResultEvent and FaultEvent have the mx_internal method callTokenResponders() which triggers the response. So the solution is pretty straight-forward: create the appropriate Result(Fault)Event object, passing an AsyncToken,  and call callTokenResponders() .  See ControllerTest.test_loadDataXML_result().

Share

Written by Sam Ahn

January 30th, 2010 at 12:54 pm

Posted in flex

Tagged with , ,

Flex Application View Organization

with 2 comments

The way I develop software regularly evolves as I learn better practices, and this is particularly true in the way I organize view code in Flex applications. I've seen (and built) too many applications where the code is unncessarily difficult to jump into and maintain. Inspired by domain-driven design and test-driven development, I've been organizing view code in such way that I believe helps maintainability and also helps answer the question, "Where should I put this component?".

Here are some guiding principles:

  • The view code should reflect how you talk about the application with the entire team.
  • The view code should reflect how you interact with the application.
  • Repeating yourself can be a good thing.
  • Components and events should be contextual.

Let's way we have an application that manages contacts. There's a list of all your contacts on the left. There's a list of recent contacts on right right. The selected contact's detail shows up in the middle. There is also a Twitter feed widget in the contact's details. Here's a wireframe:

Here's how I would create the view package:

com.foomonger.contactmanager.view.ContactDetailsView
com.foomonger.contactmanager.view.contactdetails.events.ContactDetailsEvent
com.foomonger.contactmanager.view.contactdetails.TwitterFeedWidget
com.foomonger.contactmanager.view.AllContactsView
com.foomonger.contactmanager.view.allcontacts.ContactItemRenderer
com.foomonger.contactmanager.view.RecentContactsView
com.foomonger.contactmanager.view.recentcontacts.ContactItemRenderer

So what did I do? I created components that reflected the wireframe. There is a component for each major section (all contacts, contact details, recent contacts). I named the Twitter component "TwitterFeedWidget" even though I thought the "widget" part was dumb but that's what the product owner and overall team calls it. I also created a ContactDetailsEvent class within an "events" package specific to the ContactDetailsView component. That may be a bit extreme for some people, but I find that it helps me keep track of the purpose and scope of view events. I also created a ContactItemRenderer for both the AllContactsView and RecentContactsView. Even if the code was identical in each item renderer, I prefer to keep them distinct instead of having a common one in a generic "itemrenderer" package. I argue that what I lose by repeating myself I gain back in maintainability. If there was a common ContactItemRenderer, after many months of new feature development with several developers it'll be easy to lose track where it's used. If the item renderer has to do something different in one particular case you can of course add properties and states to keep it multipurpose. However I've found this to be regression prone. If you have distinct contextualized components, you can be more confident that a change will not cause regression elsewhere.

I used to always look for even the slightest resemblance of a pattern and abstract all kinds of code into shared components. But I've realized that developing an application is different from developing a component library or a framework. In a component library you can have a generic color picker. In a framework you can have a generic "itemrenderer" package. I'm not saying you can never do these things in an application, but I am saying that I think application development should be very (domain) specific.

Share

Written by Sam Ahn

November 21st, 2009 at 11:38 pm

Agile Refactoring

with 2 comments

There's always something to refactor. Requirements evolve, short-cuts are taken, code doesn't get reviewed, and anti-patterns emerge.   How does refactoring fit into agile development? How do you have to convince the product owner to make a refactoring system story a high priority for the next sprint? How do you address that crumbing design pattern a random contractor setup years ago?  Here are some practices to help address these issues:

Document areas to refactor. When you have to take a short-cut to hit a deadline, first of all comment the code and then create a ticket to address the short-cut in another sprint. I also suggest tagging the ticket as "technical debt." This will give your team visibility into the amount of technical debt that is accrued.

Include refactoring into story estimations. If you know that a story would be best implemented if you refactored some code, don't start off by giving an estimate that assumes you'll use a short-cut. It can be natural to people-please and say things can be done sooner but try to avoid that and keep in the mind the goal of writing high quality software which includes refactoring.

Clean up the small things when you see them. Refactoring doesn't have to be a clean sweep of the whole house, it can be just a good habit of picking up things along the way. I wouldn't recommend rewriting significant logic for fun, but if you're in some code and find that a minor change would significantly improve readability then it might be worth the few minutes to do the cleanup.

Break down large refactoring changes into manageable tasks. You'll never have the time to do that gigantic overhaul of that terrible reporting system (or what-have-you) all at once. What you can do is break it down so that the work can be spread out across many sprints. This effort can be complex so I suggest starting by creating a task to outline all the changes that should be made.

Evaluate and convey the business value of the refactoring need. It's likely difficult to find a product owner who will add a refactoring system story into a sprint just because you tell them it'll make the code better. There's no apparent business value in that reason.  Think of the issue from the product owner's perspective and consider the "so that" part of the system story. Ask yourself, "Would it improve system performance? lower technical debt? improve throughput? address the root causes of the growing list of bugs?" You may even find that the refactoring you wanted to do doesn't have significant business value and is just clean and maintainable enough the way it is.

One of the great things about agile development is the exposure and mitigation of risk. If a system needs significant refactoring then that's risk that the entire team should be mindful of. Refactoring can then be something that happens, not just something you want to do.

Share

Written by Sam Ahn

November 10th, 2009 at 8:39 pm