Tim's Unnecessarily Strict Style Guidelines
(TUSSG)
UPDATE: TUSSG is no longer a requirement for any future
assignments. I decided that learning the compilers rules, the general
conventions, and a few course conventions is bad enough without adding my
conventions.
The following guidelines are suggestions for Mini-assignments A and B as well as
Course Assignments 1 and 2. You may are free to ignore them but if you
find them useful you may certainly continue (I recommend continuing to keep
rules 2 and 4). There are many shortcuts in Java, and taking them without
understanding what they are shortcuts for doing is a recipe for disaster.
I have had three semesters helping students write code in the labs, and I have
specifically chosen four rules that I think will be useful for CS302 students.
You must follow the
course
style guide. The course style guide is mostly about formatting
your code while TUSSG is mostly about statements that you must use.
Some of the rules may not make sense until we cover certain topics. For
example, rule #4 will be irrelevant until we cover "if" statements in week 5.
Rule #1: Never give a variable a value in a
declaration.
Why it is unnecessarily strict:
You may give a variable a value in the same statement that declares it.
This is a very convenient shortcut, and it is often a very good idea to give
variables values immediately.
Why Tim's making you do it anyway:
Creating a variable and setting it's value are fundamentally different
operations, just as building a crate and putting something in them are
fundamentally different. While an experienced programmer is at no risk of
confusing the two, I have found some students unable to explain the
difference. I want the difference to be completely clear in everyone's
mind. By the time I stop requiring TUSSG, I expect you will be able to use
the shortcut without risk of confusion.
Be sure to give values to instance variables in the constructor rather than at
their declaration.
Example:
Instead of writing:
String lastName = "Norris";
You must write:
String lastName;
lastName = "Norris";
In the Book:
The book actually recommends the opposite on page 37. Once you
understand the difference between declaration and assignment (and TUSSG is no
longer required), you may wish to always give values to variables you declare.
Rule #2: Never assign to parameters
Why it is unnecessarily strict:
A parameter is a variable, and it can legally be assigned to. Sometimes
this may be somewhat useful and can keep you from declaring another variable.
Why Tim's making you do it anyway:
Occasionally I have seen 302 students assign values to the variables that hold
the parameters. It usually means that the students do not understand what
a parameter is and what it does. Assigning to a parameter is erasing the
information you were given to correctly perform the function. This is a
bit like tearing up a sheet of paper that describes your next homework
assignment--there may be some reason to do it in certain cases (maybe you made a
backup), but it's probably a bad idea.
While there are times when you can perform a method correctly using the
parameter as an extra storage space, you can always declare a local variable and
use that instead.
Example:
Instead of writing:
public static int square(int num){
num = num * num;
return num;
}
Try using:
public static int square(int num){
int result;
result= num * num;
return result;
}
or even better:
public static int square(int num){
return num * num;
}
In the book:
The book recommends the same policy on page 303 (Quality Tip 8.3)
Rule #3: Always put [xxx]. before any field or method you
use
(Where [xxx] is the object or class for the field or method. If this is
confusing, see the examples)
Why it is unnecessarily strict:
When inside a (non-static) method that will be called on some Object name
foo, if you want to access some object's instance field you must specify
which object's instance field you want. There is one exception: if you
want to access one of foo's instance fields, you need not specify what object
you are refering to. Simply typing the name of the instance field is
sufficient.
The same holds true for instance methods. You need to specify which object
the method is called on unless you call it on foo.
Similarly in class named Bar, with static fields and static methods, you must
specify which classes field or method you want, unless you want the class Bar.
Why Tim's making you do it anyway:
It is terribly important to realize that if you have an instance field called
"count", there may be many, many such variables--one for each object of that
class. So when you want to add one to count, you are not being specific
enough. Which count? When you say just count, Java assumes you mean
this.count, which is a good default (Recall that this holds a reference to the
Object the current method was called on). However, I think that some
students miss who's count it really is, which rapidly leads to a large number of
confusing and incorrect notions.
This reinforces some very important concepts in Java.
Every instance field belongs to an Object, so always specify which Object.
Every (non-static) method is called on an Object, so specify which Object you
are calling the method on. Each static field belongs to a class, so
specify which class. And every static method is called on a class, so
specify which class.
The added bonus is that typing this will make Eclipse provide a drop down menu
of your options you can select from.
Example 1:
Incorrect example for instance fields and non-static methods. Suppose we
have a class called Counter that contains an instance field named "count" and a
non-static method called increment(), and you wish to write a method that takes
a second Counter as a parameter and increments this object if it is smaller and
the other one it it is not, do not write it like this:
public void incrementSmaller(Counter
anotherCounter){
if(count
< anotherCounter.count){
increment();
}else{
anotherCounter.increment();
}
}
Instead write it like this:
public void incrementSmaller(Counter
anotherCounter){
if(this.count
< anotherCounter.count){
this.increment();
}else{
anotherCounter.increment();
}
}
Notice that the second example really explains where we are getting each
count from.
Example 2:
Incorrect example for static fields and static methods:
If we want to write a class for calculating the circumference of a circle from
the radius or the diameter, instead of this class:
public class CircleMath{
public static final double PI =
3.14159265;
public static circumferenceFromDiameter(double
diameter){
return PI *
diameter;
}
public static circumferenceFromRadius(double
radius){
return
circumferenceFromDiameter(2 *
radius);
}
}
Write it like this:
public class CircleMath{
public static final double PI =
3.14159265;
public static circumferenceFromDiameter(double
diameter){
return
CircleMath.PI * diameter;
}
public static circumferenceFromRadius(double
radius){
return
CircleMath.circumferenceFromDiameter(2 *
radius);
}
}
In the book:
Page 101 suggests that it may be a good idea to always use this with
fields. Common Error 3.2 suggests that it may be worth doing for
methods.
Rule #4: Always include braces with if's, else's and
loops.
(The course style guide lists this as a recommendation--with TUSSG it is a
requirement)
Why it is unnecessarily strict:
You only actually need the braces if there is more than one
statement. Braces effectively combine several statements into one
statement (called a block statement), so adding braces to one statement does
nothing.
Why Tim's making you do it anyway:
Instead of having braces on some and none on others, all will have braces.
Not only is this more consistent, it also removes two frustrating
problems. When editing code I wrote earlier, I have a few times added a
second statement but forgotten to add braces, which can cause puzzling
behavior--the second statement is not actually inside the if statement.
The other problem is the dangling else problem, which is described in common
error 5.2 of the book.
I have learned my lesson the hard way and now follow this rule in my own
code. An added bonus is that you may now use Eclipse's brace
matching--double click the end of a brace and Eclipse will automatically select
everything that brace and its matching brace include.
Example:
Instead of writing:
if(age < 18)
System.out.println("You may not vote");
else
System.out.println("You are old enough to vote");
You must write:
if(age < 18){
System.out.println("You may not
vote");
} else {
System.out.println("You are old enough to vote");
}
In the book:
The book suggests doing this for nested if statements on page 181.
Last updated 2-12-2008