Cephi Systems Software and Contract Services

25Apr/110

Java Article 24: Constants and the DRY Principle

Constants are a variety of static fields in Java. Constants are aptly named: They are intended to represent one immutable value, i.e. they are constant.

Constants are convenient because you can specify a value in one place verses specifying the value every time you need it. Also constants prevent you or another programmer from unintentionally changing the constant’s value somewhere else int he program. The use of constants is common in all kinds of software applications, especially in scientific and engineering applications, where you could be working with something like the ideal gas law.

Below are a couple of methods from an application calculating pressure and temperature with the ideal gas law:

public static double calculatePressure(double numberOfMoles,
double temperatureKelvin, double volumeLiters)
{
//Pressure = nRT / V
double pressurePascals =
(numberOfMoles * 8.314472 * temperatureKelvin )
/ volumeLiters;

return pressurePascals;
}

public static double calculateTemperature(double pressurePascals,
double volumeLiters, double numberOfMoles)
{
//Temperature = PV / nR
double temperatureKelvin =
(pressurePascals * volumeLiters)
/ (numberOfMoles * 8.314472 );

return temperatureKelvin;
}

Instead of entering the 8.314472 each time the value for R is needed you could declare it as a constant since you expect this value to never change. You do this by using:

public static final double IDEAL_GAS_CONSTANT = 8.314472;

The naming convention for constants is all caps with underscores between words. This helps you and other programmers identify them easily. The constant’s declaration uses the modifier static (meaning it is associated with a class rather than just an object), and the modifier final. The final modifier is what makes the constant immutable, as demonstrated below:

public class MainClass
{

public static final double IDEAL_GAS_CONSTANT = 8.314472;

public static void main(String[] args)
{
IDEAL_GAS_CONSTANT = 34.333; //error: this can not be changed
}

}

The use of constants is also a very basic example of using the Don't Repeat Yourself (DRY) principle of software development put forth by Hunt and Thomas in The Pragmatic Programmer. The DRY principle states "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."

In our example if you were to enter 8.314472 throughout your program you could make a typo resulting in a calculation error. Possibly even with dangerous consequences since we are working with gasses under pressure.

Using the constant IDEAL_GAS_CONSTANT is less prone for error. Typically if you make a typo here you get a “cannot be resolved” error from the compiler.

Another reason it is good to use constants is if a user came back and told you they needed a constant changed so the software performs better. Suppose you have a value in 20 different places in your program. First, it is much faster to change the value of one constant than it is to change the value in 20 different places.

Second, suppose you are changing the values and you only end up changing 19 of them, missing one. This type of error is very common in both programming and technical writing. Following the DRY principle helps prevent this kind of error.

Another reason to use constants is that constants are evaluated at compile time, while other variables are evaluated at run time. Using constants will give you a slight performance boost.

Depending on the architecture and complexity of your program you can declare your constants in different places:

  • If you have only one class, put your constants in that class.
  • If you have many classes needing the constants, put the constants in their own class or even multiple classes.*
  • If your constants are sets of named values like days of the week, or car models and their weights consider using an enum.
  • You should also plan for future growth (extensibility). If you think it is likely the number of classes in your program will grow, and additional classes will need your constants, put the constants in their own class to begin with, so you don’t have to change it later.
  • You can put your constants in an existing protocol, but it is often frowned upon to just use a protocol to store constants.

* Be careful with constants in their own classes: If you later change the class containing your constants and you don't recompile the other classes that reference that class, you will end up with both old and new values in your program.

Another thing to look out for is if you have a class with a constant you can declare and initialize a constant with the same name in a subclass, creating a new memory location with its own value. This is called shadowing, and results in 2 constants with the same name but with potentially two different values. You can prevent other people from shadowing your constants in a subclass by declaring the superclass final.

The console application below demonstrates the basic use of constants:


public class PressureCalculator 
{

	public static final double IDEAL_GAS_CONSTANT = 8.314472;
		
	public static void main(String[] args) 
	{
		System.out.println("Pressure = " + calculatePressure(5.0, 300.0, 1.0));
		System.out.println("Temperature = " +calculateTemperature(12471.708, 1.0, 5.0));
				
		/* 
		 * You reference a constant in another class by the 
		 * class name same as a static variable:
		 */
		System.out.println("Constants.SOME_CONSTANT_ONE = "
				+ Constants.SOME_CONSTANT_ONE);
		System.out.println("Constants.SOME_CONSTANT_TWO = "
				+ Constants.SOME_CONSTANT_TWO);
		
	}
	
	public static double calculatePressure(double numberOfMoles,
			double temperatureKelvin, double volumeLiters)
	{
		//Pressure = nRT / V
		double pressurePascals = 
			(numberOfMoles * IDEAL_GAS_CONSTANT * temperatureKelvin )
			/ volumeLiters;
		
		return pressurePascals;
	}
	
	public static double calculateTemperature(double pressurePascals,
			double volumeLiters, double numberOfMoles)
	{
		//Temperature = PV / nR
		double temperatureKelvin = 
			(pressurePascals * volumeLiters ) 
			/ (numberOfMoles * IDEAL_GAS_CONSTANT );
		
		return temperatureKelvin;
	}
}

Here is our class that hold our constants:


/* 
 * a constant can be shadowed, thus changed in a sub-class,
 * so declaring your constant containing class final will
 * prevent this. 
 */

public final class Constants 
{
	public static final double SOME_CONSTANT_ONE = 1.1;
	public static final double SOME_CONSTANT_TWO = 2.2;
}

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

No trackbacks yet.

Christian Louboutin outlet, Christian Louboutin sale, Christian Louboutin replica, Louboutin outlet, Christian Louboutin outlet