Swiz, Signals, and [MediateSignal]
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).
Testable-Driven Development
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 Model Presentation 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.
Mocking Loader and Services
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().
Flex Application View Organization
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.
Agile Refactoring
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.
Google App Engine, Django, Flex, and Facebook
RPSConquest was my first Google App Engine/Django/Flex/Facebook application. It's a turn-based rock-paper-scissors game played within Facebook. I built it to learn a variety of technologies and to see how well those technologies worked together. I was particularly interested in using Google App Engine and learning Python. In this post I'll elaborate on the technologies used, discuss curveballs I faced, and share some conclusions.
Technologies:
- Back-end:
- Google App Engine (SDK 1.2.4)
- Python (2.5.4)
- Django (1.0.2)
- Google App Engine Helper for Django (revision 90)
- PyAMF (0.5)
- PyAMF Test Client (Slightly modified from the original Test Client)
- Pyfacebook (0.1)
- Front-end:
- Development Environment
- Windows XP
- Eclipse
Flex has been my primary technology over the past couple years, and I wanted to build a Facebook game with it. I'm addicted to the Swiz Framework so I continued to use that (instead of Cairngorm). The app required a Flex Facebook-Friend-Selector component so I also needed the Facebook ActionScript Library for the FqlQuery command.
I planned to build an AMF service layer for the Flex app and almost went a LAMP/Zend setup on my personal web server. I was introduced to Google App Engine by a colleague and quickly went with it because of the automatic scalability and free quota.
App Engine currently supports Java and Python, and I went with Python because the Django framework sounded really interesting. Using the Google App Engine Helper for Django almost seemed like a must for a newbie like me.
There were a couple AMF libraries for Python, and I first tried DjangoAMF but quickly found it to be unusable for my Flex 3 app. I ended up using PyAMF which worked out really well. I wanted to write unit tests (which Django is great for) and found that I needed a test client for the remoting classes. I founded one on a random blog post and added it to my PyAMF files (with some minor modifications). With the remoting test client and the Django test client I was able to write and debug unit tests for all my AMF services.
My app needed to notify Facebook users and post messages on walls. Instead of doing this on the client-side, I did this in Python with Pyfacebook.
Instead of using the standalone Flex Builder, I used Eclipse with the Flash Builder 4 and Pydev plugins for development environment. I was able to locally debug both Flex and Python code all while running the app within Facebook (thanks to port-forwarding).
Curveballs
Version Compatibility
Though it was documented, I still stumbled with the version compatibility of Google App Engine, Python, and Django. Be sure to double-check what works with what in the latest documentation.
Locally Running the Python Server to be Available through Facebook
For local development I created a development Facebook application which pointed to my machine's IP address using port forwarding and dlinkddns.com. What I didn't understand until I read the docs more carefully is that when I ran the development Python server using "manage.py", it defaulted to the IP address 127.0.0.1 (on port 8000) which prevented Facebook from being allowed to hit the server even though it could hit my machine. I ended up using "manage.py runserver 0.0.0.0:8000" which allowed Facebook to hit the development server.
Google App Engine Datastore is not a Relational Database
Before I decided to go with App Engine I had sketched out my model to create tables in a MySQL database. I had about a half-dozen tables which in Django directly correlates to a half-dozen model classes. As I was developing the business logic I learned that the App Engine datastore is not a relational database. I couldn't do joins. That forced me to significantly refactor and basically de-normalize my model down to 2 classes.
These links helped me understand what was going on:
Mocking or Lack Thereof
The service code uses Pyfacebook and requests data from Facebook. I didn't want that code to run during unit tests largely because it wouldn't have the proper session keys. I briefly looked into mocking some of the Pyfacebook code for the unit test but without success at first pass. I cheated using a settings flag so that code wouldn't be run during unit tests to just get the features done for now. I hope to properly learn mocking in Python in the future.
Facebook Session Keys and AMF
From my understanding normally HTTP requests from a Facebook application would contain a bunch of Facebook data such as session keys. With AMF service calls, those HTTP requests do not have that data so the facebook object that the Pyfacebook middleware creates doesn't have some values set such as the session key. And that session key is needed for some of the API calls I was using. I ended up not using the middleware according to this post, manually created the facebook object, and manually set the session key which I parsed out from authentication data sent to the service methods. The authentication data was based on the Facebook fb:swf notes which allows you to verify that the swf was loaded from your Facebook app.
Facebook One-line Story Publishing
I was very confused about how my application should post messages (stories) to Facebook users' walls and the permissions it required. For now I wanted to avoid explicitly asking for elaborate permissions. Posting one-line stories seemed like it didn't require the "publish_stream" extended permission. I ended up making sure the user was logged in, that the app was added to the user, and using the feed.publishUserAction API. I didn't use the recommended stream.publish API because it appeared to only publish "short stories" which required extended permissions.
Conclusions
I loved using Python and Django. I found Python to be a very friendly yet powerful language and Django to be a very efficient yet powerful framework. It let me quickly build up a tested AMF service layer. I'm very curious about the future of Django in commercial projects.
I think using Google App Engine, Django, and Flex is a great way to quickly build scalable Facebook applications. You definitely have to get used to programming for App Engine though. If you're not afraid to commit to coding specifically for App Engine then it seems like a great solution. I think development speed and scalability are key aspects in social media application development. This combination of technologies seems to address those aspects very well.
Courage
Practicing agile development for the past year or 2, I've been thinking about the concept of courage more and more. Courage seems to be a common value of many frameworks (e.g. Extreme Programming), and I think it makes a lot of sense especially when taking into consideration test-driven development and domain-driven design. I've personally found that embracing courage makes me more productive in writing code by helping me make decisions more quickly and empowering me in general.
I think the same type of courage goes beyond the code and should be consciously applied to development overall. The goal of software development in business isn't excellent code quality after all but instead to meet some sort of business objective. For example, I think it takes courage to realize you've underestimated the complexity of a task and to come back to the product owner/client/manager and say "We screwed up and totally overlooked this when we implemented that. The consequences are this and that." I think it takes courage to say half-way through an iteration, "We just realized that we can't do all of this in time, but we can do this small part." This isn't anything new, and from my understanding good agile teams do this well naturally. I like to think of these things within the concept of courage because of the empowerment angle.
So while embracing courage within a programming context makes me more productive in writing code, I've found that embracing courage within an overall development context makes me more productive in creating business value. I can't say I do this all the time, but it comes to mind, at least subconsciously, with every hurdle I encounter. I think that in the face of imperfection, unexpected complexity, and evolving requirements, software development needs more engagement and with more engagement, more courage.