Archive for the 'Design Patterns' Category

Upgrading to Wordpress 2.3.2

How unsexy are Wordpress security updates? I have the horrible habit of doing everything else first before attempting one (which, of course, is absolutely the worst thing you can do, as the recent spam hack on the SWX blog demonstrated so well). I used to dread doing the updates mainly because I just knew something would break. At least that's how I used to feel.

When I last upgraded Wordpress, a little over a week ago to version 2.3.1, I made a slightly delayed New Year's resolution that I wouldn't hack the blog. Instead, I decided to do everything using plugins and widgets (which are plugins that display on your sidebar). And -- wonder of wonders -- I actually stuck to it! That being the case, upgrading is no longer a nightmare.

In fact, when you have an unhacked Wordpress installation, all you have to do to upgrade to 2.3.2 is:

  1. Download 2.3.2.
  2. Delete the wp-content folder and the sample wp-config file from the distribution.
  3. Test it locally on your development machine (skip this step at your own peril; the last thing you want is all your readers discovering your "Doh!" moment mistake at the same time as you do!)
  4. Upload the new files to your server.

That's it. All in all, it took me under ten minutes to do. As there were no database changes between the two versions, I didn't even have to run the upgrade script (which I realized after running it on my local installation and seeing the resulting message.)

The moral of the story is that if you don't hack your blog but use plugins for everything, upgrading no longer needs to be a nightmare. Using a plugin-based architecture (which in Wordpress shares similarities with aspects and the Template pattern in object/aspect-oriented programming) gives you flexibility in customizing something without altering the original, thereby making updates to the original possible without breaking your customization.

The same moral holds true for development when you're using third-party libraries. Instead of hacking them, see if you can't extend their capabilities either via inheritance, or, even better (because it's more flexible), through composition (say via the Decorator pattern or by using interceptors). That way, unless the public API of the library changes, you won't be afraid to update the library to its latest version. (And, if you're designing an API, see if you can't include some hooks or filters in there to make it easier for people to extend it without too much trouble.)

To cut a long story short, the blog's now running Wordpress 2.3.2 and all is well. It's also a real pleasure to actually find myself looking forward to the next Wordpress update rather than dreading it! :)

FOTB slides: Memo to the CEO

I've just put my slides up from my Memo to the CEO session at Flash on the Beach. Download them here (PDF, 3MB).

I thought about exporting QuickTime and Flash versions of the presentation too but, frankly, I couldn't justify it. The QuickTime version has all the bells and whistles of the transitions but it staggeringly large. The Flash version, well, let's just say I'm sure that Apple didn't cripple the Flash export on purpose but in terms of size (it's large) and performance (it doesn't have all the effects), it really doesn't make much sense. Again, I'm sure it's not a case of Apple favoring QuickTime over Flash! At the end of the day, the PDF version seems to be the best bet. It contains the information and is small. There you go, you just read a whole paragraph on why you've got my session slides in PDF format. Truly, could there have been a better way for you to spend the last thirty seconds. Thirty one. Thirty two! :P

While searching around for a picture to include in this post, I also found some reviews of my session. Here are some links:

Flashing at BarCampLondon

Aral Balkan's Agile Development and Usability presenation at BarCampLondon.

BarCampLondon was a blast! Over the course of a weekend, I got to meet some amazing people, catch up with friends, learn some great stuff (including a new game called Werewolf) and get inspired. Big thank-yous to Ben Metcalf, Ian Forrester, Murray Rowan, and Paul Hammond for organizing the event and for your tireless omnipresence throughout the weekend. Similarly, thank-yous to Yahoo! UK, eBay, BBC Backstage, TechChrunch, Chinwag, and Belkin for sponsoring the event with food, drinks and network cables! And, of course, thank-you to everyone who attended for making the event what it was, for sharing and for lynching me so early in the game -- I wasn't a werewolf dammit! :)

My first session was titled Agile Development and Usability. It was a one-slide presentation in which I talked about the three big problems I see our field faced with today. Namely, a lack of understanding of development process, of the importance of the user and of application architecture. I followed this up with a high-level overview of solutions to these problems, including the use of Agile Development (with examples from eXtreme Programming/XP), User-Centered Development and usability patterns and pattern-based architecture. I ended the half-hour session with a brief glimpse into how these solutions can be implemented in projects for the Flash Platform using Flex 2, Arp and open source tools.

After my first session, I got a couple of requests for more information on Flex 2 and decided to hold a separate talk on just that subject on the second day. In that talk, I gave an overview of the Flash Platform, Flex 2 SDK and Flex Builder 2, using my Flex 2 Quick Starts for the examples.

In addition to presenting, I also got to attend quite a few presentations by other people. You can find notes from those sessions in the BarCampLondon category. Without fail, the sessions I attended were all highly engaging and informative. I can only surmise that the quality of the attendees and the BarCamp format had a great role to play in this.

You can find links to other media from the event on the BarCampLondon What Happened wiki page.

So, when are we going to have the next one? :)

Cairngorm Commands now same as Arp Commands

I just read that Cairngorm 2 (Beta 3), released by the Adobe Consulting folks, now has stateless commands like the ones in Arp. Very cool! :)

AOP vs. The Interceptor vs. The Template

No, it's not some crazy tag-team wrestling line-up. I was side-tracked in one of my Googling expeditions and came across a blog entry by Ted Neward titled Setting the Story Straight: AOP != Interception. In it, Ted provides an interesting comparison of the Interception pattern and Aspect-Oriented Programming.

Interception and AOP also have parallels with the Decorator pattern, filters and the Template method (in which you set up your Template methods so that they call hook operations that can be overriden by subclasses.) These concepts and patterns can be useful in Flash and ActionScript development too. For example, the Template pattern is used for the base classes in ARP and I had used Interception in the past to decorate the functionality of a method (I'll be damned if I can remember what exactly it was for.)

After reading Ted's post, I thought I'd whip up a reusable way to easily decorate methods and came up with the Aspect class presented below (it should perhaps rather be called Interceptor or MethodDecorator.) The Aspect class allows you to modify the behavior of a method by specifying that another method (which I've called an Advice, following the term used in AOP) be executed before (default) or after the method.

This is a naive first implementation and I have neither given it too much thought nor tested it out exhaustively so treat it as experimental code and feel free to send me suggestions and improvements. Here it is for you to play with...

// Class: Aspect
// Allows you to weave in advice (other methods) before and after the original method.
// Copyright (c) 2005 Aral Balkan
// Released under the MIT License.
class Aspect
{
    var originalObject:Object;
    var originalMethodRef:Function; // Reference to the original method
    var originalMethodName:String;
    var copyOfOriginalMethod:Function; // Local copy of original function
    var advice:Function; // Code to weave in
    var after:Boolean = false;
 
    function Aspect (obj:Object, methodName:String, advice:Function, after:Boolean)
    {
        originalObject = obj;
        originalMethodName = methodName;
        originalMethodRef = obj[methodName];
 
        // Save a local copy of the original method
        copyOfOriginalMethod = obj[methodName];
 
        // Save the advice method
        this.advice = advice;
 
        // Should the advice be executed after the original
        // method? (Defaults to false so the advice is executed
        // prior to the original method.
        if (after != undefined) this.after = after;
 
        // Overwrite the original method with a proxy function
        // to relay calls to the Aspect object
        obj[methodName] = function()
        {
            // Call the execute method on the Aspect
            arguments.callee.aspectRef.execute.apply (arguments.callee.aspectRef, arguments);
        }
 
        // Add a reference to this instance on the
        // target method's activation object so it has a
        // way to refer to us.
        obj[methodName].aspectRef = this;
    }
 
    // Executes the advice and the original method.
    function execute()
    {
        // Should the advice be applied prior to the original method call?
        if (!after) advice.apply (originalObject, arguments);
 
        // Original method call
        copyOfOriginalMethod.apply (originalObject, arguments);
 
        // Should the advice be applied after the original method call?
        if ( after ) advice.apply(originalObject, arguments);
    }
}

To test it out, enter the following script into the first frame of an empty FLA placed in the same folder as the Aspect class:

// Create the original method
originalMethod = function() { trace ("Original method") };
 
// Create two new advices
firstAdvice = function() { trace ("Before original method") };
secondAdvice = function() { trace ("After original method") };
 
// Create the two aspects
firstAspect = new Aspect(this, "originalMethod", firstAdvice );
secondAspect = new Aspect(this, "originalMethod", secondAdvice, true);
 
// Call the original method
originalMethod();

The output should be:

Before original method
Original method
After original method

I'm sure you'll find some cool uses for this! :)

The Problem with View Helpers

In my post on the Ariaware RIA Platform (ARP), I mentioned that while working on the first release of Opal, we had implemented View Helpers as part of our pattern-based framework for that project. Although this seemed like a good idea at the time, as the application grew, I noticed that it was partly responsible for much of the code duplication we started to experience. This led, among other things, to us not incorporating View Helpers into Bits and Pixels' own, AS2-based framework, ARP. (ARP also differs markedly from the Opal framework in our implementation of the various patterns, including the event broadcasting and handling model as well as the behavior of the controller and commands.)

Working with Telrock Communications, we are currently refactoring the Opal framework to bring it in line with the best practices pattern implementations we developed for ARP. These include, among other things, removing the View Helper classes (and encapsulating View Helper methods as public methods within the various forms/screens themselves) and adding view references to broadcasted application events (to be used by the Command classes). But why are we undertaking such a large-scale (and thus risky) refactoring of the base code in the run up to a second release? The answer, as always in refactoring, is to remove duplication.

A Command pattern implementation that does not allow the commands to receive view references leads to a very unhealthy duplication of Command and View Helper classes. As we all know, duplication is bad and refactoring is the answer. We actually noticed this issue late in the game in the run up to the first release of Opal and though we should have refactored it there and then, we decided that we couldn't afford the project risk at that point in time. Whether or not that was the right decision can be debated. Personally, I believe that Kent Beck couldn't be more correct when he states that the right time to refactor is the moment you notice duplication. This is related to one of the most important tenets of eXtreme Programming: Courage. (The courage to refactor when necessary.)

The removal of View Helpers is necessary to achieve better encapsulation and reduce code duplication. With the View Helper functionality neatly encapsulated within the various forms/screens themselves, we remove the need for code duplication (through the duplication of View Helpers) when composing new, aggregate screens or extending existing screens. With Commands receiving view references, we remove the need to duplicate Command classes when extending screens or composing new screens from one or more existing ones.

With these refactorings in place, the Opal framework should behave in a functionally equivalent manner to the Ariaware RIA Platform. Among other things, this is expected to result in a considerable file-size reduction in the application and aid in its scalability and maintainability.

I know that Lindsay has undertaken certain refactorings on the Java side of things (and quite possibly has plans for some more). Perhaps we'll be lucky enough to get an update from him in the coming days! :)






Bad Behavior has blocked 0 access attempts in the last 7 days.