The contour package is a simple text editor based on one of the
tutorials that comes with the JBuilder Java development environment.
tutorial was designed to exercise JBuilder's graphical UI development tools, and is not a particularly good example of object-oriented design: almost all of the code is contained in a single class
Nevertheless, the step-by step development process that is described in the tutorial notes provides a good illustration of how conventional OOP fails to achieve code locality---in other words, code related to a single function is spread through a number of methods or classes.
Good locality is maintained until Step 10, when the
String that serves as the model
for the Text Pane is connected to a file by two methods,
saveFile, which are in turn
connected to the appropriate menu commands. Here the tutorial code
also introduces a "dirty bit" to record whether the file has changed
since it was last read from or written to disk, and in Step 11 this
Boolean is used to change the behavior of some of the other methods.
Our aspect-oriented version of the program maintains all of this as
the ChangeMonitor aspect. (Click
here to see it in a
separate browser window.)
Line 17 introduces a new instance variable
changed into all objects of class
TextEditFrame. (Why into the
Frame and not into the Model? Because the tutorial example has
no real model; it is all interface. The closest it comes to a model
of the file is a Java
Lines 19 through 26 take care of resetting
changed when necessary:
immediately after a successful
(corresponding to the File > New
changed is assigned
false. Because opening or saving
a file might fail, the weave checks the result of the method
thisResult, line 24) before
Lines 28 to 37 set
event handling method is invoked. The body of this method is:
void textArea1_textValueChanged(TextEvent e)
statusBar.setText("Editing " + currentFileString());
Since there is no need to set the text in the status bar more than
once, if the before weave finds that
changed is already true, it
returns immediately. However, if
changed was false, it sets
changed to true and then falls through to the ordinary method body,
which will update the status bar as expected.
Lines 39 to 49 optimize away the
saveFile action when the file has
not changed; in this case the before advice simply beeps and
Lines 51 to 79 introduce a new method
TextEditFrame objects; it returns
true if it is permissible to abandon a currently active editor
buffer. The final two advise weaves (lines 81 to 89 and lines 91 to
98) use this method to ensure that the contents of a changed editor
buffer are not abandoned in error when a file is opened, or when the
buffer is cleared, or when the user quits the editor.
The second aspect (in file Caption.java) contains all of the code
related to updating the caption at the top of the window. First we
updateCaption(...), and a
maintains a cached copy of the current caption, and which is used to
avoid unnecessary calls to the windowing system. Five pieces of
advice are then offered: after advice to the
TextEditFrame constructor, and
the methods for
saveFile and the New menu event.
and before advice on the method that handles the
Some care is necessary to ensure that the two aspects and the
original code interact correctly. For example,
updateCaption(...) takes a
Boolean argument that tells it whether the buffer is "dirty", and
which is rendered as an asterisk in the caption. This is much cleaner
than relying on the changed variable, which is part of another
aspect, because changes to that aspect could introduce subtle bugs.
Similarly, the advise weaves that reset the caption when a new buffer
is opened must be after advise, because the
okToAbandon method called from
the before advise on the same method might have prematurely
terminated that method's execution.
The aspect weaver generates Java files that can be compiled and run in any Java programming environment. Although not intended for human consumption, the generated code is quite readable, and viewing it offers an interesting perspective on the weaving process.