ChiMu  
 
Menu Edge About   Products   Services   Projects   Publications  
  Publications > ChiMu Java Standards      Previous Page Previous TOC Next Next Page

Method Standards

Summary

I use intention revealing method names where parameter positions are interwoven into the name by the inclusion of underscores "_". Any underscores at the end of the name (before the open parenthesis) are omitted from the name. Generally a method's name will uniquely determine the number and types of parameters it requires, but if there are a large number of parameters, the signature may not be unique without including the number of parameters. It is a rare and very controlled condition for when I will have two methods with signature's that are unique except for the type of a parameter.

I have many standardized words (especially prefixes) used in naming methods which reveal what the method does. I do not use "get" as a prefix for asking about an attribute (see below for the discussion of attributes).

Examples

dictionary.atKey_put(key,value);

Woven parameters

person.name();

GetAttribute

person.setName(newName);

SetAttribute (if necessary and atomic)

array.atIndex(index);

"at" is not overloaded to take both a key (Object) and an index (int)

person.isHappy();

Returns Boolean

factory.paintCar_using(aCar,white,quickly)

Extra unwoven parameters

Intention revealing method names

Having "intention revealing method names" is the primary rule for naming methods. Create a name that suggests what the method "provides for the caller", not how the method accomplishes this service. The clearer you can make your methods behavior by the name of the method, the easier it is for the client (who repeatedly uses your method) to understand your class or interface. This is one of the many incarnations of thinking from the clients perspective. See the coding pattern "Intention revealing selector" in [Beck 96].

Standard method name patterns

The next rule after picking intention revealing method names is to standardize the vocabulary used in the name. As much as possible, words should be used consistently and uniquely when part of a method. The following is an example subset of the standard meanings for method name parts and method categories (see the Source code format section below).

The following are common method prefixes

Prefixes

Category

Description

is, can, has, will

Testing

Return a Boolean and test the state of the object

copy


Copying

init, setup

Initializing

These methods are called before you can use an object. Only a single init function should be called which can then be followed by whatever setup methods you need to change the default configuration of the object. Some objects require calling a "doneSetup" to allow them to prepare themselves for normal, post initialization, interactions.

to<Type>

Converting

Produce a copy of the object converted to a different type

new

Creating

Create and return a new object from a factory that creates only a single type of object

new<Type>

Creating

Create and return a new object of a specific type

A few type specific prefixes are:

find

Searching

Retrieve a single object or null if unsuccessful

select

Searching

Retrieve multiple objects or an empty collection

value

Evaluating

Evaluate the function and return an object

execute


Execute the procedure, no return value

add


Add an object to a collection

Non-prefix method name patterns

with

This prefix is used to add subsequent parameters to a basic method when the parameters have no distinguishing features (an example is the "value, valueWith, valueWith_with" series for Function objects)

any

Return any object that satisfies the request (findAny)

all

Return all objects that satisfy the request (selectAll)

Within each Type or domain area (Collections, Functors, SQL, Mapping, Domain models) there will be both reused vocabulary and new vocabulary.

Java method signatures

Java selects the method to execute based on the name of the method, the number of parameters to the method, and the declared (not actual) types of the parameters to the method. [Gosling+JS 96, §8.4.2] Together these form the signature of the method.

To produce good code, the developer needs to make it easy for the client of the code to do what was intended. The developer, the client, and the compiler must all agree on what will happen when the program executes; it should be easy for a client to remember what methods are needed and how to call them. Allowing differences in certain features of a signature to change what method is called makes life harder on the client.

The first problem is with using the declared type of a variable to modify what method is called. This makes it harder for the caller to realize they are calling the wrong method because the information used to decide which method to call is spread over two locations: the actual method call and the variable declaration. For example, given the methods:

   void doItTo(Person person);
   void doItTo(Company company);
   void doItTo(Object anyObject);

the call to a method:

   doItTo(person);

is not enough to determine which method is called. Even if the object in the variable person is really a person (not a company), it will depend on whether the variable 'person' was declared as type Person or as only a general object. In general I consider this to be unacceptable, so I only use this feature (overloading of signature based on a parameters declared type) in very controlled circumstances (See below).

The second problem is having the number of parameters determine different behavior of methods. Although it is visible which version of the method you are calling (simply count the parameters), it is unclear what the purpose of the parameters are and what order they should be placed in. Although I do allow methods that are only distinguishable by the number of parameters, I try to avoid it.

Standard for method signatures

My standard for method signatures is to have them be mostly distinguishable by name. Ideally two methods with the same name will take the same number and type of arguments. In infrequent cases the number of parameters will determine what method to call, but this primarily happens when a method has a significant number of parameters (4 or more) so the "Parameter positions interwoven into the method name" pattern is cumbersome.

The only time the type of a parameter will determine which method to call is to support using literal values (Strings, Numbers, and Booleans) as direct parameters. These types will always be incompatible with the "standard" type of the parameter. For example, if the standard method requires an object of type Person, say "Company#firePerson(Person p)", it is acceptable to have a method with an identical name that takes a String instead of a Person in that parameter position "Company#firePerson(String personName)". This is disapproved of, and it would be better to name the method "Company#firePersonNamed(String personName)". Usually this is only a problem when a set of related messages all have a significant number of parameters (4 or more), so the names are not likely to be unique.

Parameter positions woven into the method name

A general problem with parenthesized parameters is that there is no reminder of the order of parameters. This is especially true of methods with more than two arguments, but can also be a problem even with only two parameters. Examples of these problems are:

   hash.put(value,key)         // put value at key? no, wrong order
   statement.setObject(index,type,value)   // set the entry at index to the type using value?

Generally Smalltalk has less of a problem with this because the parameters are woven into the method call, which encourages a much higher level of readability. The example of a method definition in Smalltalk is:

   Dictionary>>at: key put: value

or to put it into close to Java terms:

   public void at: Object key put: Object value {...};

Because of this message weaving, we have come up with a clearer name "at:put:" instead of just "put", both of what the method does and especially of which parameter is expected in what position. Even though Java does not allow this type of syntax, it would be nice to encourage these improved message names and to have the messages describe to the client using the message what order to put the parameters.

First Solution

The first solution I used was to put underscores "_" as place holders to identify where a particular parameter is woven into the message send. For example:

   at_put_(key,value)

would read as at_(first parameter)put_(second parameter) or "at (key) put (value)". The second example would be:

   setIndex_to_asType_(index,value,type)

or "set index (index) to (value) as type (type)". This does a good job of specifying the meaning of the message, the number of parameters, and the specific positions of all the parameters. If you have a large number of parameters that you do not want to specifically mention/weave into the method name, you can use a double underscore to indicate two or more values. For example:

   at_putStuff__(key,value1,value2,value3)

Although this was a very consistent and logically understandable solution, all the added underscores were annoying, especially because the underscores at the end of the name visibly separated the method name from the parameter list. Those trailing underscores were also the hardest to remember to put in, probably partially because they were not really part of the "spoken name" itself: it is easy to pause within a name, but hard to express a pause at the end of a name.

Current Solution

A better working solution is a hybrid approach. Put in the underscores just as before, but drop all trailing underscores. The examples become:

   at_put(key,value)
   setIndex_to_asType(index,value,type)
   at_putStuff(key,value1,value,value3)

So there are underscores to indicate the position of all parameters except the last one (and any unwoven ones). This means "put(value,key)" is also valid, because it has an intermediary form "put__(value,key)" and then the underscores are dropped. Although "put" is valid using the standard, it is still an inferior method name to "at_put" which reveals intention and its use better.

Because the trailing underscores have now been dropped, we can not tell how many parameters a method takes. We know the minimum: 0 if no underscores and 1+#underscores if there are any. Unfortunately we can not tell the difference between 0 and 1, or between 3 and 7. Luckily other standards or the obvious intention of caller make these not much of a problem: calling a method that requires no parameters (asking about an attribute) is so significantly different from calling a method that requires a parameter (setting an attribute) that they are not likely to be confused.

Attributes

An attribute is a public property of an object that shows the state of the object. Frequently there is a minimal collection of attributes that uniquely determine the state of the object, but this should not be confused with the instance variables which may be used to store that state.

No ‘get’ prefix for attributes

I do not use the prefix "get" to ask the value of an object's attributes. This is noisy and is without any benefit. A method sounding like a noun indicates an attribute, which distinguishes it from a method that changes the state of an object (which will use an active verb).

Attribute setting

Not all attributes are changeable, in which case they will not have a setter. Not all attributes can be changed independently (state transitions should be as valid and complete as possible), in which case they will not have a setter, but will instead be changed as the result of another method. Finally, if an attribute is independently changeable it will have a setter with a signature of the attribute name prefixed with "set", returning "void", and taking a single argument.

Instance variables

An instance variable is an implementation detail of a class and should be "private" or "protected". Whether I wrap an instance variable with private get/set methods is dependent on the needs of the class. I never use the ability to access another object’s (of the same class) instance variables except in "clone" type methods.

 
Publications > ChiMu Java Standards Previous Page Previous TOC Next Next Page