Flex :: Framework forks and subclasses
Order and logic rule our consciousness, thus seeing a template in a framework comes natural for me, I love order.
What is a fork relating in a framework? When creating abstract superclasses that rely on subclasses to fill in details we need forks. A micro routine in a macro routine. Take the flex framework, the commit properties fork is a very important and extensible piece of logic. This code path enables you to set any property, composite property or micro routine that a measurement or update to the display list relies upon.
Take for example a routine that needs subclasses to create bars and set visibilities of those bars. This routine needs to happen before measure() and updateDisplayList() is called becasue the viewMetrics and/or size may change when a new bar (in the component's chrome) comes into existence.
From the sentence above we have abstracted two routines that fork from the original commit properties fork.
- creation of bars
- setting of bar visibilities
Lets look at some code structure;
{
super.commitProperties();
// if any barvisibilities changed
if (barVisibilitiesChanged)
{
commitBarVisibilites();
barVisibilitiesChanged = false;
}
}
// fork 1
protected function commitBarVisibilites():void
{
visibleBars = new Dictionary(true);
validateBarVisibilites();
updateBarVisibilities();
}
// fork 1A
protected function validateBarVisibilites():void
{
if (_showTitleBar && !titleBarInstance)
{
createTitleBar();
}
visibleBars[TITLE_BAR_NAME] = _showTitleBar;
}
// fork 1B
protected function updateBarVisibilities():void
{
if (titleBarInstance)
{
titleBarInstance.visible = visibleBars[TITLE_BAR_NAME];
}
invalidateSize();
invalidateViewMetrics();
}
commitProperties()
- commitBarVisibilites();
- visibleBars = new Dictionary(true);
- validateBarVisibilites();
- createTitleBar();
- create the instance
- visibleBars[TITLE_BAR_NAME] = _showTitleBar;
- createTitleBar();
- updateBarVisibilities();
- titleBarInstance.visible = visibleBars[TITLE_BAR_NAME];
- invalidateSize();
- invalidateViewMetrics();
With this algorithm we may now subclass this component and add new bars. The subclass needs to override
- validateBarVisibilites()
- updateBarVisibilities()
the super class takes care of the base logic, subclasses just add to this fork and use it's two new forking ends.
There is a rule in abstraction you must learn. If you plan on creating a useful fork, you need to plan and create a base method commitBarVisibilites from our original super class fork that now calls new sub forks, validateBarVisibilites and updateBarVisibilities.
For any type of useful subclass overrides to efficiently override this fork and provide maximum flexibility, the base method is required so that any logic in the first fork (validateBarVisibilites) is encapsulated from the second fork (updateBarVisibilities).
With this scenario you have three override possibilities;
- override
commitBarVisibilites() - control before and after sub fork run.
- override
validateBarVisibilites() - control inside run
- override
updateBarVisibilities()- control inside run
Also, if abstracted correctly, you can call these methods individual. The purpose of a fork within the flex framework is to provide decoupled micro routines that are not dependent on it's caller. This is a very important rule. By making the two micor routines dependent on commitBarVisibilities you have now spun a web that a subclass cannot get out of.
When you subclass this fork, you for all intents and purposes copy what is in the two micro routines and leave the concrete implementation to the super class that has defined this code path.
The code examples are listed just to show what this 'might' look like. I do have this implemented in my framework but, there are other subtle things going on since this is a non trivial property commit.
The dictionary values are used in method like showAllBars(), hideAllBars(), restoreBars(), etc. It allows use to either explicitly hide/show or remove bars during transitions to save performance while restoring them when the transition is complete. This way we do not touch our component showBar properties.
UPDATED ::
From Toms comment, the Flash Player is a single thread. Yeah it is and most of us know this. I speak English and fork means multiple directions from the point your at. If I was talking about threads in the Flash Player I would be wrong. But, I'm not.
I am trying to say, in an abstract sense of the word [fork], the flex framework has code forks due to how the Template Method pattern is implemented. This article explains how to utilize this routine path and how to create new roads from an existing path.
PS, If some one else wants to comment on my English, I can do a search and replace.
Mike
September 26th, 2007 at 7:59 am
I’ve never come across ‘fork’ used in the is context before, and the player is single threaded so the normal compsci context doesn’t apply.
Do you have other resources that explain more about it ?
September 26th, 2007 at 8:37 am
Tom,
I should have said :
fork = [code branch fork, code logic fork, fork in the road… etc], the word is not talking about threads and yeah it’s misleading but this is a blog that is in my own words.
I am a visual person and fork is a visual word for me.
As far as resources, no, this is from 2 years of experience in the flex framework. Besides, where do resources come from anyway.
Mike
September 26th, 2007 at 9:23 pm
Excellent. Thanks for the post.
November 21st, 2008 at 2:26 pm
Well, in the context of the Template Method pattern, the term hook is used to describe those methods that provide default behavior that can be overriden in the subclass.