Refactoring the Eclipse Framework API into Features
As you doubtless know, gentle reader, I did my thesis research on software frameworks. Specifically, I found that client code interacted with frameworks quite consistently, and I developed a technique, called design fragments, to specify patterns of client-framework interaction. Client code is still scattered around many classes, but the design fragments make the connections between these classes apparent.
An open hypothesis was that it was possible to refactor the frameworks to avoid the scattering of code in client classes. If such refactoring were possible, client code dealing with a particular feature, say adding a menu item, would be located in a single place. Client code would be easier to read and might not need design fragments. So if a client wanted to create a user interface with a tree view and a menu, the code might look something like this:
public class SampleView extends GView {
public SampleView() {
this
.useFeature( new TreeViewFeature() )
.useFeature( new LocalToolbarMenuFeature() )
}
}
Now that I’m done with my PhD, I have some time to a) breathe and b) work on side projects. This posting is an interim report on the framework API refactoring I’ve accomplished.
Design Choices
- Subclassing (MyTreeViewFeature) vs composition — relate to type system checking
Feature Interactions
The feature interaction problem is well known inside of telephone systems. In that domain, you may have call waiting and 3-way-calling features on your telephone, and they interact with each other because they both use the same scarce resources: the telephone input and output. For example, if you are talking to a friend and press the hook once, it will allow you to start a 3-way-call. However, if someone calls during another call, that same hook press will transfer you over to another call. I had experience with this problem when I worked at Nortel, helping to design a clean-sheet implementation of their call processing software.
- Found feature interaction problem here
- Reused solution from Nortel of cascading state machines.
- Examples from this domain, dependencies between features
Summary
Good
- No show-stoppers yet
- Initial refactoring into features
- Opportunity to make framework state machine more evident
- Opportunity to use static analysis to check feature composition
- Opportunity to use static analysis to check invariants across the state machine
- Framework API collapsed into one interface
Indifferent
- On-going development of a nested event state machine
Bad
- Feature interaction has surfaced
- Strong typing in Java eliminates some (seemingly elegant) design options
- Framework API collapsed into one interface