Order in the Class

(the Protocols plug-in revealed)

by Sten-Erik Bergner
se.bergner@bergner.se

1       Introduction.. 2

2       Protocols Overview... 3

3       Brief Reference Guide.. 6

4       Related Work and Acknowledgements.. 13

 


 

1       Introduction

1.1       Background

The Protocols plug-in for the Eclipse Java development environment is about organizing class and interface definitions for readability. It applies to any Java type that is not trivial in size, say, with a two figure number of methods.

The basic idea is that a definition becomes more readable when related members appear together. This is true regardless of if reading is done through a browser or directly from the source file. But then, there’s a problem...

1.2       The Problem

The problem looks a bit different depending on your outset. Here are three versions for three common ways of working given vanilla Eclipse.

·         If you manually place each member in source code file exactly where it intuitively should be:

You will spend a lot of time thinking about topography for optimal readability, because the beauty and readability of the code is quickly lost if you relax. You hesitate to use browser based functionality like drag and drop and refactoring because of the housekeeping that inevitably will follow. Obviously, productivity suffers and in addition, the payoff is uncertain, because intuition does not always communicate after all.

·         If you sort members in a predefined order based on kind and name.

Given what’s there in the development environment, this choice emphasizes productivity but sacrifices readability. You don’t have to think about the ordering, it’s a given; and you can use automatic sorting (on the fly in the Members or Outline view if you are browser oriented and don’t worry about what source file looks like, or using the new Eclipse command: Source > Sort Members if you do worry). With this approach you can either choose to ignore the members grouping issue all together, or resort to common name prefixes to bring members together.

Given that grouping is inherently good, it follows that the former stance is not and we will leave it at that. The latter (using prefixes) is workable but ugly. Names tend to loose in quality as the ideal name must be sacrificed for one that starts with the right characters. In order not to totally obscure the actual member name, prefixes have to be kept short which limits the possibility for the programmer to communicate what the commonality between the members of the group really is. Because of the unattractiveness of the results of this solution, classes will tend to have too few methods as each new method adds a stone to the burden.

·         If you create sections in your source code file with headers using lots of / and *, placing members in a predefined order within each section:

This is a potentially productive compromise. By partially using a predefined ordering you do not have to rely so much on intuition this way and the headers could be made long enough to convey comparatively rich semantics. Headers can also be reused across classes and interfaces further reducing the burden on the writer and gaining in readability as the reader will learn what to expect under a recurring header.

But then there are tool problems that substantially limits the productivity gains. To begin with a showstopper, if you are browser oriented, forget this approach given the standard Eclipse. The key information carriers, the headers, will not even show up in the browsers. If this is not a problem, then managing the manifestation of headers in the source becomes an issue as its a manual text editing task. And above all, standard automatic sorting (Source > Sort Members) will wreck havoc to the structure, so keeping section members in the predefined order becomes a completely never-ending manual task.

1.3       Conclusion

Of the three, the partial ordering technique using headers would be the obvious choice were it not for the tool issue. Disregarding that, it allows for efficient production of class and interface definitions with the readability enhancement that we pursue.

So what needs to be done is to introduce, into the programming tools, the notion of grouping members under headers, and to make them support the various tasks involved.

Of this support we require:

·         That it is compatible with both browser oriented and file oriented editing styles.

·         That each header does not have to be edited manually.

·         That the ordering of groups and their members is automated.

·         That it does not interfere—at least do no harm

1.4       My Solution

I have realized the above outlined support in the form of a plug-in for Eclipse that I call Protocols. The name is intended to lend recognition to the original grouping feature, in the Smalltalk-80 programming environment.

2       Protocols Overview

2.1       Proviso

From the very first, I want to make absolutely clear that in the design of the Protocols plug-in, one requirement has had precedence over all other: At least, do no harm. When Eclipse is used, after the Protocols plug-in has been installed, it can be safely ignored. Type definitions will not be required to include headers, nor does the Protocol View (see below) have to be used. When headers are used they can be used heavily or just a tiny bit. They are just code comments, with no strings attached.

2.2       Presentation

The Protocol plug-in supports partitioning the source code into sections using a comment or set of comments as the header of each new section. The headers exact manifestation is defined by the user as a user preference. The members appearing below a header belong to the section, so the source code reads like a regular document. The sections, known as protocols, may be browsed in a new view called the Protocols View.

Apart from that the appearance of the headers in the source can be varied, the above screen shot pretty much captures what the current version of Protocols does presentationwise. In the following we will address how the protocols are managed.

2.3       Ordering

The protocols are sorted in accordance to the user preferences of the Protocols plug-in. But within a protocol, the members are sorted in accordance to the standard workbench user preference Java > Appearance > Members Sort Order.

Keeping everything in order is done automatically as far as the editing operations offered by Protocols are concerned. However, because there are many other ways of changing a class definition, a protocol-conscious version of Source > Sort Members, called “Sort and Format” is provided that enforces the predefined ordering throughout a source code file.

2.4       Spacing

Related to the above, when members and protocols are moved around, in and out of the source code, spacing (keeping to a consistent number of blank lines to separate members) becomes an issue. Spacing is defined as user preferences, and abided to by all built-in editing operations of Protocols. The “Sort and Format” operation enforces consistent spacing throughout a source code file. (This is the whole “Format” part; it does not touch the actual code.)

2.5       Protocol Names

The name of an existing protocol can be changed simply by changing the header directly in the source code, though afterwards, “Sort and Format” may be required to move it to its correct position. But the name can also be changed through the “Rename” command which offers two advantages. One is that the Protocol with its members automatically will be repositioned as called for, The other advantage is that, as an alternative to simple typing a new name, the user can select a name off a list of predefined “standard” names.

Standard names helps reduce annoying deviations in naming, half the time using the protocol name Access and half the time using Accessing. But more importantly, it lessens the demand on the user to make yet more decisions and helps create patterns for how names are used. Standard names are defined as user preferences.

New Protocols are created analogously through the “Add” command or directly in the source by simply copying and pasting an existing header and changing the name.

Protocols can be cut or copied from one Protocol View and pasted into another. Alternatively, drag and drop can be used. Either way, only the protocol itself is added, not the members from where it was taken. This shallow copy interpretation is more useful than a deep as it facilitates the reuse of sets of protocol names between types. If the members are wanted as well, this only requires an additional command, which leads us on to the next topic.

2.6       Assigning Members to Protocols

Members may be assigned to protocols in either of four different ways:

·         Drag and drop from a Members View into the Protocol View.

·         Directly editing the source code.

·         By copying or cutting from a Members View and pasting into the Protocol View.

·         By the “Assign to Protocol” command in the Members Views context menu.

 

2.7       The Default Protocol

As stated initially, classes and interfaces are not required to have Protocols. Thus, members are not required to belong to a protocol. In the source code, such members appear at the top, before the first header if any. In the Protocol View they are presented as belonging to the Default Protocol which works as any other Protocol in respect to moving members around. The Default Protocol can not be removed but there is an option to hide it when empty.

2.8       The Header Representation

Under Protocols’ user preferences, the user can specify the header, the chunk of comments that are to be used for denoting the start of a new Protocol in the source code. It is therefore not unlikely that different representations are used by different programmers, or the same programmer, at different times. To make this possible there exists a scheme to record and discover the representation used in a file containing protocols. This is simply what can by described as an empty protocol with a predefined name, “-----“, following the last member. To the pedestrian it looks like a “The End” sort of thing, at least that’s the intention, but to Protocols it is a declaration of the header representation used in this particular file.

Consequently the user preference specification is actually only used for adding the first protocol.

3       Brief Reference Guide

3.1       The Protocols View

In this first version, the Protocol View is only intended for the Java Browsing perspective. In other words, it connects with the Types View and Members View but not, for instance, with the Hierarchy View.

The Protocol View displays the protocols of one Type, selected in the Types View. Protocols with no members are marked with an outlined icon, the others with a filled. If displayed the Default Protocol is always at the top.

If the Members View is open, selecting one or more Protocols will limit the members displayed to those belonging to the Protocols. If no Protocol is selected, or if the Protocols View is closed, the Members View will display all members as usual.

There are two pull down menu commands:

Default Always

If checked, always show the Default Protocol. If not checked, hide the Default Protocol if no members belong to it.

All Lowercase

If checked, display Protocol names in lowercase only. If not checked, display Protocol names in actual case.

 

3.2       The Protocols View Context Menu Commands

The context menu of the Protocols View offers the following commands:

Add

Create a new Protocol by either choosing a predefined name (see Preferences) or “Other...” to enter an arbitrary name. Names already in use in the Type are disabled.

Rename...

Change the name of a single selected Protocol. Existing names will be disallowed.

Cut

Move the members if any of the selected Protocols to the Default Protocol, remove the protocols and place it on the global clipboard.

Copy

Place copies of the selected Protocols on the global clipboard.

Paste

Adds the content of the clipboard to the Type definition. Members copied from (typically) the Members View as well as Protocols from Protocol Views can be pasted. With members, the user will be queried for a receiving Protocol. With Protocols, only the Protocol itself is added, no members. The command is disabled if the clipboard content is inadequate.

Remove

Move the members if any of the selected Protocols to the Default Protocol, then remove the protocols.

Refresh

Update the display of the Protocol View. Useful because all source code changes that might affect it are not necessarily broadcast by the Java Editor. Notably such that are limited to only changing a comment (as is the case when a Protocol name is changed via the source code rather than the Protocol View).

Sort and Format Source

Sort the Protocols and the members within each protocol (including the Default Protocol if any, i.e. any members that do not belong to a protocol). Also enforce consistent spacing between the elements of the file. This is the whole “Format” part; the code is left untouched.

Note that within each protocol, the members are sorted in accordance to the standard workbench user preference Java > Appearance > Members Sort Order.

3.3       Other Commands and Gestures

In addition to the above, a few commands are introduced in existing menus and there is also support for drag & drop which provides a convenient way to reuse protocol names as well as to allocate members to protocols.

Sort and Format Source (On the context menu of the Types View)

Same as the “Sort and Format Source” on the Protocol View context menu.

Sort and Format (On the context menu of the Java Source Code Editor)

Same as the “Sort and Format Source” on the Protocol View context menu.

Assign to Protocol... (On the context menu of the Members View)

Assigns the selected members to an existing or new Protocol.

Drag and Drop members

Dragging members from the Members View and dropping them on a Protocol in the Protocol View will assign the members to that Protocol. By dropping in the Protocol View but not on a Protocol the members can be assigned a new Protocol.

Drag and Drop protocols

Dragging Protocols from one Protocol View to another will add the Protocols, but not their members.

3.4       The Preference Pages

There are two preference pages for customizing what the Protocols plug-in does: Protocols and Protocols > Names. This is the former:

The first three options apply to the Protocol View:

Always show the default protocol in the protocol view

If unchecked, the virtual Default Protocol will not be displayed if it is empty, i.e. if all members have been assigned to a (real) protocol. If checked, the virtual Default Protocol will always be displayed.

Only use lowercase in the protocol view

If unchecked, the Protocol View will display protocol names exactly as they appear in the source code headers. If checked, they will be converted to lowercase when displayed in the view which may be more fitting with Java naming conventions.

Name to use for default protocol in the protocol view

The virtual Default Protocol does not correspond to a header so the name is specified here rather than in the source code.

When members are moved in and out of protocols by commands, source code gaps between members need to be closed and new gaps have to be created. The next three options are used to specify the gap size resulting from editing and to be used by the “Sort and Format” command.

Number of blank source code lines to separate Field declarations

The number of blank lines to separate consecutive field declarations.

Number of blank lines to separate all other Member declarations

The number of blank lines to separate consecutive member declarations when not both are fields. This spacing will also be applied between a header and an immediately following member declaration.

Number of blank source code lines to separate Protocols

The number of blank lines to separate any member declaration from an immediately following header.

The final option is the specification of the header representation. It will be used in whenever the first protocol is added, by an Add command, Paste, or drag & drop, to a source code file. Changing this specification will not have any retroactive affects, nor will it inhibit the proper interpretation of existing headers.

Comment(s) to represent the start of a new protocol in the source code

Type or paste the source code lines that are to constitute a header. The “${Protocol Name}” part is a placeholder for the protocol name, which pressing the “Place Name” button will move to wherever the cursor is.

Unless you are up to something unexpected, each line needs to be either blank or part of a comment. Editing commands of Java Browser Perspective tend to regard Javadoc (/**...) comments preceding a member declaration as part of that declaration, so non Javadoc (/* and //) style comments are recommended. (Some commands feature the unfortunate habit of regarding more or less all comments as belonging to an adjacent members declaration; see the Bugs and Limitations section for a detailed run down.)

The Protocols > Names is concerned with the sorting order of protocols (which is based on names) and the specification of standard protocol names:

All three options on this page require the specification of a list and use a four button list editor for this purpose. Unfortunately, there is no way to copy names between lists in this version.

The first option constitutes the basis for the standard protocol name support

Standard protocol names for easy selection when adding protocols

These are the protocol names that will be offered directly off the Add menu and in the drop down list of the Add Protocol dialog box. The order specified here will be used in these two cases.

The following two options specify the protocol sorting order. It is used for the source code as well as for the presentation in the Protocols View.

This is how it works: Protocols are sorted in three categories: top, middle (alphabetically ordered), and bottom. All protocols not belonging to top or bottom, belong to middle; so this is where all protocols that are not named here end up. Protocols belonging to the middle category will be placed in alphabetical order following any protocols belonging to top category. Bottom category protocols will be placed below any middle category ones. Top and bottom category protocols are sorted within their category as specified in the lists.

This scheme allows you to have some protocols which, if they are present, always are presented first or last.

Ordering of protocols to appear above the alphabetically ordered

The names of the protocols that are to appear at the first in the source code and in the Protocols View. Note that this means directly following any members that have not been assigned to a Protocol. The order specified here will be used when more than one of these protocols are present.

Ordering of protocols to appear below the alphabetically ordered

The names of the protocols that are to appear at the last in the source code and in the Protocols View. The order specified here will be used when more than one of these protocols are present.

3.5       Bugs and Limitations

·         When changes are made to the source, the Protocol View may become a bit out of synch if the changes are deemed insignificant (as for instance changes in comments are) and therefore not immediately broadcasted by the text editor. Things go back to normal again when more changes are made or if the Refresh command is used in Protocols View.

Some of the commands of the Java Browser Perspective may be harmful to source code organized using headers and need to be used with discretion. These problems are directly related to the use of headers rather than the Protocols plug-in. However, the plug-in provides workarounds in some cases:

·         Sort Members must of course be avoided whenever headers are used. The Sort and Format command is provided in its place.

·         Drag & drop of members into classes and interfaces treats adjacent comments in different ways, most of which are bad, at least for headers, depending on style and spacing(!). At the time of writing comments may be moved, duplicated or even lost as a result of drag & drop (see e.g. Bugzilla Bug 41734). As a workaround, drag & drop of members into the Protocol View works fine and can be used to move within, and move or copy between, classes and interfaces.

·         The Cut and Delete commands in the Members View removes all preceding comments not separated from the deleted member declaration with at least on blank line, and all succeeding comments separated from the next member with at least on blank line. It must therefore be used with a large amount of care in order not to lose headers.

·         The Show Source of Selected Element Only text editor mode will show all comments preceding the selected member. This means that a header will be displayed as part of the member definition when the member directly succeeding the header is selected. Luckily, this has no adversary affect beyond being a bit disconcerting.

The various anomalies regarding the treatment of comments mentioned above have been registered in Bugzilla as Bug 46171.

·         Some more or less obvious creature comforts are missing from this first version. I would be happy to receive your suggestions for the next.

4       Related Work and Acknowledgements

As already mentioned, Protocols originally appeared in the Smalltalk-80 programming environment. Before me, Chris Grindstaff created an Eclipse plug-in called “xdoc” based on the protocol idea. It was xdoc that got me started on Protocols. Thank you Chris and thanks also to Simon Tardell for pointing me to xdoc, beta test, and providing valuable suggestions.