Top 10 in 2008
5 popular archives:
All selections are based on page views.
JW hot topic: Tech careers in a slump
Seems like new layoffs are announced every week, projects are dying and software developers are feeling the IT budget squeeze.
Being nervous isn't a crime, but you're better off with information, advice, and a plan.
From the IDG News Network:
The completely green pastures of software development are rare these days, with many development assignments having some history or legacy associated with them. The reality is that these historical elements often translate themselves into constraints that must be dealt with. These constraints can manifest themselves in a multitude of areas, from hardware and network configurations, to programming language choice and software design. This article will focus on the latter and illustrate how two classical Gang of Four design patterns, Decorator and Command, can be used together within existing applications to assist in their maintenance.
For any exercise in maintenance there first must be some code to maintain. I will describe a billing application that contains a similar design and, hence, is constrained in a similar manner to one I encountered recently.
Pretend you have been brought in to maintain a billing application for an Internet service provider (ISP). This application handles the ISP's billing requirements. It calculates the following set of charges:
While sifting through the code, you notice that these calculations are implemented as command objects. A command's intent, according to the Gang of Four, is to:
"Encapsulate a request as an object, thereby letting you parameterize clients with different request, queue, or log requests, and support undoable operations."
Simply speaking, a command can appear as an object-oriented function pointer. It encapsulates a method invocation into one object. So in our system, there are different command classes for the different types of calculations in the system. Separate classes calculate joining fees, monthly usage, and excess consumption. Figure 1 shows these classes.

Figure 1. All calculators in the system
All the calculation command classes implement a generic command interface. This allows the rest of the application to treat different calculations generically:
public interface Calculator
{
public BigDecimal calculate(BillingContext context);
}
The interface accepts a BillingContext that holds the necessary data for the calculation to occur and returns a BigDecimal, representing the amount to be charged.
Let's look at a simple calculation class that implements this interface. This class calculates a user's monthly usage fee using this formula: rate (in dollars per MB) multiplied by consumption (in MB):
public class UsageCalculator implements Calculator
{
public BigDecimal calculate(BillingContext context)
{
return context.getRatePerMB().multiply(context.getConsumptionInMB());
}
}
A unit test ensures that this class functions as expected:
public class TestUsageCalculator extends TestCase
{
private static final BigDecimal CONSUMPTION = new BigDecimal(100);
private static final BigDecimal RATE = new BigDecimal(0.50);
public void testUsage()
{
UsageCalculator usageCalculator = new UsageCalculator();
BillingContext context = new BillingContext(CONSUMPTION, RATE);
// 100 * 0.5 = 50
assertEquals("Charge not as expected", 50, usageCalculator.calculate(context).intValue());
}
}
I have omitted other calculator implementations, but you should be able to see how classes similar to UsageCalculator can exist to cater to the system's different calculation types.
Archived Discussions (Read only)