Advanced ActionScript Refactoring – Step 1
In the intro, we talked about the problem we want to tackle, which is to refactor DragTile to be more flexible. If you haven’t read it yet, you might want to check it out.
Back? Ok. Now, let’s look at some code.
Step 0 – the starting point
The original files for my investigation can be downloaded from Ely’s site, or you can get my slightly munged version here.
Step 1 – pull up the FlexibleContainer superclass
Even though we said we were going to use composition instead of inheritance to separate these classes, we do this as a first step because it is easier than pulling out a helper class.
Tip 3: Always refactor in small steps that leave the external behavior unchanged
The basic procedure is to create a superclass (which I called “FlexibleContainer”) and to walk through the DragTile code method by method and property by property to move things to the superclass if it seems appropriate.
I started by moving all of the local variables that seemed “general” to the superclass. This included the _items array, the renderers array, and so forth. The variables that seemed specific to the Tile layout were left in the DragTile class.
Because most of these variables were private, moving them to the superclass caused a lot of compile errors, most of which I fixed by moving the appropriate methods to the superclass.
In one case (dragTargetIndex) I needed to create a protected accessor so that the subclass could get at this information. If you want to be a stickler about it, making a private member protected requires some thought. Is this the right way for a subclass to get information from its superclass? In this case, it’s probably not the right thing. The “right” thing is probably to pass the drag information as a parameter during the drag operation. This brings us to the next tip:
Tip 4: When refactoring, don’t try to make it “perfect”. Just strive to incrementally improve the code each time you touch it.
Creating a protected accessor here was the quickest way to separate these two classes without overcomplicating the design. We can come back and fix this later after the dust has settled.
At this point, the FlexibleContainer class and the DragTile class have been completely separated. The outlines look like this.
Original API:

After the first refactoring, the new API looks like this. Remember that our goal here is to put all the logic that is specific to a specific layout (Tile) into one class, leaving as much of the general code in the superclass as possible. The DragTile class should be as small as possible (but no smaller!) :

Source code for step 1 can be found here.
“…making a private member protected requires some thought. Is this the right way for a subclass to get information from its superclass? In this case, it’s probably not the right thing.”
What’s wrong with letting a subclass use a protected var belonging to its superclass? I’m kind of curious as I don’t really see the use of protected members if you shouldn’t let subclasses use them (since that’s in my opinion the only difference between private and protected)..
Thanks for the thoughts, Ruben. You’re absolutely right. Making a variable protected is, by definition, a way to give permission to subclasses a chance to use the variable.
What I meant to say is that before you decide to make a variable protected, you should think about whether it would be better to leave it private and provide a different way for the subclass to access the information.
In this case, exposing dragTargetIdx as a protected variable is arguably the wrong thing. It is a very specific implementation detail of how drag and drop was implemented by the superclass, and you may want to change this in the future. The “right” way to factor this is to make the variable private and to give the subclass some other way of getting the information. (for example, by passing the drag target index into a drag handler function as an argument).
Sho, that is an interesting point. Normally I would create a protected internal var and a public accessor for outside classes to access.
However, while reading your comment it occured to me that when creating a protected accessor for a subclass to access, the private attribute might actually have some use (for marking the internal var).
This is actually the first situation in which I would prefer private over protected.
Having said that, I still think I like protected better for all other situations. In my opinion, the habit of making your vars private (instead of protected) totally ruins the opportunity for other programmers (and yourself, for that matter) to extend your classes.
This why I feel extending some of the more complicated AS3 Flex classes is a horrible (if not near impossible) task to do.
[…] Advanced ActionScript Refactoring – Step 1 […]
[…] [ç¿»è¯]ActionScript釿§‹ä¸‰éƒ¨æ›²ä¹‹ä¸€(Advanced ActionScript Refactoring – Step 1) é€™äº›æ–‡ç« ç¿»è¯è‡ªSho Kuwamotoçš„ActionScript Refactoring 三部曲,經éŽåŽŸä½œè€…åŒæ„ç¿»è¯ä¹‹ã€‚ 本文原文連çµåœ¨æ¤ã€‚ […]