JavaDude.com

-- Scott Stanchfield

Scott's Rules of Reuse

I present to you, the first publication of Scott's Rules of Reuse. Applying
the following five rules results in an incredibly safe & reusable class.
Such a class can be reused through extension or composition keeping consistent
use of state in the original class.

Scott's Rules of Reuse state:

All variable data must be private.

Most data should be JavaBean Properties.

Data must only be used in get/set methods.

Most methods should be public or protected.

Final methods and class are evil.

Details of Scott's Rules of Reuse follow.

When to break the Rules of Reuse

As in all rules in life, rules are made to be broken. However, keep in
mind that rules are also made to be adhered to!

First, never break rule #1. There is never any valid reason to
directly access a class' variable (non-constant) data from outside the class
itself. You can always add a get/set method to provide this functionality.

Otherwise, the rule of thumb for the other rules is "if you can argue
your case to the Supreme Court of the United States of America, with Bobcat
Goldthwait as your Lawyer, and win,
then you may break the rule." These rules have some very important effects,
and if followed, will greatly increase maintainability and reusability of your
code.

Scott's Rule of Reuse # 1:

ALL VARIABLE DATA MUST BE PRIVATE

NOTE: There is only one exception to this rule: final static variables (aka
class constants). Otherwise, there are to be no exceptions to Scott's
rule #1. Ever.

The reason for this is that a class must be in total control of its state. If
someone makes a change, the class must have a chance to know about it. If we
leave variables non-private, some other class can change our state w/o us
knowing.

The only way variables are to be changed is via methods defined in the class,
preferably a setXXX() method. Initially the set method is simply changing the
value. However, later on, we can add code to the set method to

add validation to ensure the value is acceptable

fire events to tell others that the value has changed

update other state when the value changes

log that the value has changed

If the variable is non-private, the set method might not be called when it
changes, so we cannot guarantee to be able to fire a property change, validate,
etc.

Scott's Rule of Reuse # 2:

MOST DATA SHOULD BE JAVABEAN PROPERTIES

(Details on this accidentally deleted -- I'll need to add them back later.
The basic gist of this is that there's usually no reason to disallow controlled
access to your data. By controlled, I mean access via methods. It's rare that
you want to really disallow get, and only occasionally useful to disallow a set.
By providing get/set methods for most (if not all) of your data, a subclass can
easily modify the state of its superclass in a safe manner.

Scott's Rule of Reuse # 3:

DATA MUST ONLY BE USED IN GET/SET METHODS

NOTE: There are to be no exceptions to Scott's rule #3 in your
handwritten code. Ever.

The only places in your code where a variable should appear are:

the variable definition

the get method to read it (or a single, designated access method)

the set method to modify it (or a single, designated mutation method)

This has two very desirable effects:

the code in set (like firing property changes) always has a chance to
run, even when you're updating the variable from within its own class

subclasses can override the way the data is get/set (the subclasses
cannot touch the variable, but can call the superclass set with modified
parameters or modify the result of a call to the superclass get)

Note that rule #3 is sometimes broken in code generated by GUI builders.
VisualAge for Java is one that does a pretty good job following this rule,
though.

Also note that some methods act in place of get/set methods to access data.
As long as you limit the number of places that actually do the reading and
writing of the data to a single reader and a single writer, you are adhering to
rule #3.

Scott's Rule of Reuse # 4:

MOST METHODS SHOULD BE PUBLIC OR PROTECTED

Note the weasel words "MOST" and "SHOULD"; there are a
few reasonable exceptions (mainly for generated code).

The reason for rule #4 is to allow subclasses to override any method they
want. This allows your superclass to just to its job w/o worrying about what a
subclass might need. The subclass can override anything that it wants,
either extending or replacing the superclass behavior for that method.

Anything that you want to "hide" from general public use should be
protected; that still allows subclasses to override and call the superclass
version (as well as allowing other classes in the same package to call them).
All other methods should be public, letting anyone call them.

Private methods should only be used by builder tools/wizards to
prevent accidental overriding of implementation details, or in extreme
cases of security issues. A good example I heard once was that someone
distributed an online game and didn't want people to override pieces to cheat...

If you want to make a method neither public nor protected, you had better be
able to present your case to the Supreme Court. You're basically asserting that
noone will ever want to change that behavior. You had better have an
incredibly good reason to use such behavior.

NOTE: "Performance" is not a valid reason to use private
methods. This can result in a minor, almost negligible, performance
improvement by inlining methods under some circumstances, but that minor
improvement is a bad trade for maintainability/extensibility.

Scott's Rule of Reuse # 5:

FINAL METHODS/CLASSES ARE EVIL

The last rule of reuse concerns the use of the final keyword when applied to
methods and classes. Final is evil. Plain and simple.

When you make a method or class final, you cut off any chance of
extension. This should only be used in exceeding rare circumstances,
usually security-related, such as the game cheating example in rule #4. If you
want to make a method or class final, it's Supreme Court case time again.

NOTE 1: "Performance" is not a valid reason to use final
methods. This can result in a minor, almost negligible, performance
improvement by inlining methods under some circumstances, but that minor
improvement is a bad trade for maintainability/extensibility.

NOTE 2: Rule #5 does not apply to final variables -- there are very
legitimate reasons to use final variables.

RE performance of inlined methods (private/final) -- there are a few
highly-computational applications where inlining makes a noticeable difference,
but all other methods of improving performance should be exhausted before making
methods private or final. These other methods include but are not limited to:

profiling to find bottlenecks

choosing better algorithms

using other compilers that might optimize code better

using Hotspot to execute the code (it inlines where possible even if not
private/final)

The above methods usually result in a higher gain than inlining can ever
accomplish.

Notes on my personal application of these rules

I have upheld rule #1 for a very long time

I've really only realized the benefit of #2 and #3 fairly recently, and
my past code does not follow it

I've followed #4 for quite some time (generated code being the
exception)

I always follow #5

And a final note, the JavaBean spec uses getters and setters to be able to
determine "properties" in your bean to show them in a GUI builder.