to control class member accessibility in an agile context; to close a project against undesired access
Information hiding suggests that the accessibility of class members should be no greater than required by their actual or designed use. However, during development, agile development especially, it is not always clear in advance which members of a class will be used and by whom. Selecting the required accessibility then becomes a speculative process, and not infrequently a wider accessibility than necessary is chosen, if only to save oneself and others the hassle of later correction. Also, changes to a program that would allow reduction of accessibility of members are often performed without this reduction, simply because one is unaware of the fact that one's changes would allow this lower accessibility. What follows is that after a project has been finalized, members with unnecessarily high accessibility persist.
The Access Modifier Modifier (AMM)
tool provides programmers with immediate information about and
control of the accessibility status of class members. All members
with excessive (i.e., higher than required) accessibility are
marked by a warning equipped with a corresponding Quick Fix,
allowing reduction of accessibility with a few key strokes.
Members of an API that are not currently used by the project (so
that their accessibility appears excessive, but is not) can be
tagged by an
annotation and are thus excluded from analysis. Members with
insufficient accessibility are nevertheless included in code
completion (Content Assist in Eclipse terminology); upon
selection, their accessibility is increased to the required
level, without changing to the source file.
The AMM verifies that no change to accessibility it suggests or performs changes program semantics. It may thus be viewed as a refactoring tool with built-in smell detection and strict precondition checking.
The AMM tool is implemented as a builder that can be added to and removed from a project. To add the AMM Builder, go to the properties page of a project and select the AMM Properties sheet:
By checking and unchecking the "AMM Builder Active" box the AMM Builder is added and removed.
The property sheet also offers the exclusion of packages from the analysis. In framework and other open projects, the packages to be excluded are usually packages that are not explicitly designed as being internal (the API packages; see Eclipse Naming Conventions and Package Naming Conventions Used in the Apache Harmony Class Library).
After closing the property sheet, the project is automatically rebuilt if so required.
The AMM builder generates a warning and a gutter annotation (marker) for each member whose accessibility can be reduced:
A quick fix is then available for performing the reduction if so desired:
API methods (including hook methods) can be annotated as follows:
public abstract void someMethodToBeCalledFromOutsideTheProject();
This prevents markers suggesting a reduction of accessibility from appearing. Insertion of the annotation is offered as an alternative Quick Fix for a reducible access modifier ("Add @API annotation"; see above).
If a member of a class is inaccessible, it can nevertheless be offered in Content Assist, by pressing Ctrl + space until the corresponding frame is displayed; selecting a member automatically increases its accessibility to the required level.
The AMM takes special care to not change the semantics of a program by changing the accessibility of members. Such care is required in case of overriding (where reducing accessibility of an overridden method may prevent dynamic binding of the overriding method) and overloading (where reducing accessibility of a method with more specific parameter type may prevent it from being called). Also, accessibility of an inherited member cannot be reduced below that of the superclass or interface from which it is inherited, and cannot be increased above that of its subclasses. Note that unlike its predecessor, the AMM cannot change accessibility of complete class hierarchies.
The reduction of accessibility is limited by interface
implementation: accessibility of members of a class required by
an interface implemented by the class cannot be reduced (see
above). Interface implementation therefore substitutes for
@API annotations. This
is a problem if the interface is designed for internal use only,
i.e., if it is not meant to be part of the API its
publicity is then carried over to the implementing classes, and
there is nothing the AMM can do about it. However, the size of
the interface can be minimized by a different tool, namely our Infer Type refactoring.
The AMM tool is installed using this update site. This Eclipse help shows you how to do it; in step 4, enter "AMM" as the name and "http://www.fernuni-hagen.de/ps/prjs/AMM2/update/" as the URL.