Before Flash/Flex, I wrote software in Python. There are several concepts in Zope/Plone/Python that are very relevant to Flex and ActionScript 3. Many people know about Inheritance and Composition but very few know about Acquisition. I am going to introduce the concept of Acquisition and show some examples of it within Flex. Looking back, understanding Acquisition has been a key factor in my personal success with Flash and Flex.
First things first, a warning. We are OOP off-roading here. If you bring your OOP preconceptions along they might get a little shaken up. Acquisition is a bit different but it fits seamlessly with Inheritance and Composition. You have been warned!
So lets start with a definition of Acquisition (Wikipedia doesn’t have a good definition, I told ya we are offroading here!):
Acquisition – The ability of any object to acquire data and behavior from surrounding objects.
What the hell does that mean?
In its simplest form, Acquisition allows you to build objects/components that change their behavior depending on where they are located at runtime. These objects “acquire” data and behavior from surrounding objects based on composition. Acquisition takes composition to its logical next step by allowing objects to be created that react to what they are within, next to, or what objects they contain.
Confused? No getting stuck in the mud, keep the peddle down. Here are some concrete examples of Acquisition behavior within Flex:
TabNavigator – This container defines navigation based on its children. TabNavigator changes behavior purely based on the objects (containers in this case) that are put within it and the order they are put in. TabNavigator reads the ‘label’ property from its children to define tabs. The Tabs in TabNavigator are obviously part of the TabNavigator component but their data is derived directly from the children within. If you remove a child, the tab is removed, if you add a child, a new tab is created, if you change the ‘label’ property of a child, the tab label changes.
I like to think of this as “Child” Acquisition as the TabNavigator looks to its children to define its own data and behavior.
Take a Button and change its label based on the parent container of the button. Put this Button in a Panel, it looks one way, put it in an Accordion, it looks different.
I like to think of this as “Parent” Acquisition as the component looks to its container/parent to define its data and behavior.
Take a series of buttons all with percentage height and add them into a base Application container set to vertical layout. Depending on the percentage size of each children, it affects the size of other children during measurement and layout. In this case, if the size of one child changes, so do all siblings within a container.
I like to think of this as “Sibling” Acquisition as a component depends on its siblings to define its data and behavior.
I believe that there are many details within Acquisition that can be applied to Flex directly given that both MXML and ActionScript 3 lend themselves to heavy use of Composition. From DOM Events to Constraint-based Layout to States, many Flex concepts depend on the runtime state of components and containers. What is fascinating to me is that we can go deeper and design systems of components that work within Acquisition to make Flex application development simpler, easier, and more reusable. Not that support for Acquisition is pre-defined in Flex per say, but I think there is a foundation in Flash Player 9 and Flex to build upon.
Here is where the rubber meets the road again and we go back to coding. Acquisition is a way to think about programming behavior into the components and objects we create. As objects can inspect parent, children, and siblings, it makes sense to program behavior that reacts to other components.
In classic Zope/Python, Acquisition is a pattern that defines a lookup tree based on composition. If you need a variable, you can lookup the tree of composition to find a definition if one is not defined within the current object. Instead of walking the inheritance chain, you walk up the composition chain of parents to the root. This way objects within another object don’t have to define all of their behavior and that behavior can change depending on how the object is composed.
Here is the summary from the Plone Manual:
Acquisition allows behavior to be distributed throughout the system. When you add a new object to Zope, you don’t need to specify all its behavior, only the part of its behavior that is unique to it. For the rest of its behavior it relies on other objects. This means that you can change an object’s behavior by changing where it is located in the object hierarchy. This is a very powerful function which gives your Zope applications flexibility.
Acquisition is useful for providing objects with behavior that doesn’t need to be specified by their own methods or methods found in their inheritance hierarchies. Acquisition is particularly useful for sharing information (such as headers and footers) between objects in different folders as well.
Here are some other resources on Acquisition:
Nature vs Nurture – John Udell
A new inheritance-like abstraction mechanism – Joseph Gil and David H. Lorenz
The class of an object is not necessarily the only determiner of its runtime behaviour. Often it is necessary to have an object behave differently depending upon the other objects to which it is connected. However, as it currently stands, object-oriented programming provides no support for this concept, and little recognition of its role in common, practical programming situations.
To give credit where credit is due, Jim Fulton of Zope deserves much credit for Acquisition, Jim wrote the initial Acquisition logic into Zope. I learned about Acquisition in working with early builds of Zope before working deeply with Flash Player. It helped me think about composition within Flash Player at runtime, defining dynamic behavior into Flash applications, and has been a key factor in my success with Flex. Call it a pattern, a tenet of OOP, environmental hoo-haa, whatever, to me Acquisition just helps me think about creating components that react to how they are organized at runtime.
In many ways Acquisition brings in the element of environment into software development and these patterns are grounded into our everyday life. My car works differently depending on the road it is on and I act differently depending on who I am around, so too with components and software. Shoot, maybe this post will be different because I wrote it on a Sunday in the comfort of my own home. :)