I l @ ve RuBoard |
As mentioned at the beginning of the chapter, shipping and taxes are two more tricky business logic subsystems. In a real application, you would have to calculate taxes and shipping costs on your orders. This usually involves interfacing to third-party APIs that do the (sometimes complex) calculations, and return a value to be placed into the order. This is the same thing you will have to do with credit card authorization. You usually won't be ready to actually integrate with the vendor's code (you might not even have chosen a vendor) when you write the code that requires that functionality. So, you'll need to stub something out for testing. A good technique for any piece of code that's going to initially function in a test mode and later have the real API added is to put in a property that acts as a switch between the stub and the real functionality. This is helpful because you might work with developers who need to test the site but who won't have access to the real clients (for example, if the tax client runs on only Solaris). With that in mind, you'll add some code to the cart to compute your taxes and shipping in Listing 12.7.
Listing 12.7 Additions to Cart.javaimport java.util.ResourceBundle; import com.bfg.customer.Address; . . . private static ResourceBundle property_bundle = ResourceBundle.getBundle("com.bfg.cart.Cart"); public double getShipping(Address addr) { if ((property_bundle.getString("testShippingMode") != null) && (property_bundle.getString("testShippingMode").equals("yes"))) { if ((addr.getState() != null) && (addr.getState().compareTo("MA") < 0)) { return countItems() * 1.25D; } else { return countItems() * 2.75D; } } else { cat.debug("No real shipping code in place yet"); return 0D; } } public String getShippingString(Address addr) { NumberFormat nf = NumberFormat.getCurrencyInstance(); return nf.format(getShipping(addr)); } public double getTax(Address addr) { if ((property_bundle.getString("testTaxMode") != null) && (property_bundle.getString("testTaxMode").equals("yes"))) { if ((addr.getState() != null) && (addr.getState().compareTo("MA") < 0)) { return getTotal() * 0.05D; } else { return getTotal() * 0.10D; } } else { cat.debug("No real tax code in place yet"); return 0D; } } public String getTaxString(Address addr) { NumberFormat nf = NumberFormat.getCurrencyInstance(); return nf.format(getTax(addr)); } public double getGrandTotal(Address addr) { return getTotal() + getShipping(addr) + getTax(addr); } public String getGrandTotalString(Address addr) { NumberFormat nf = NumberFormat.getCurrencyInstance(); return nf.format(getGrandTotal(addr)); } For the stubbed-out tax code, you're employing this "complex" calculation: If the item is being sent to a state alphabetically before Massachusetts (MA), you charge that customer 5% tax; otherwise , the customer is charged 10% tax. Although this is certainly not accurate, it allows you to see whether different taxes are being computed based on location. You can use the same technique for shipping, but in this case you'll use a fixed price per item in the cart. You also need to create the properties file that holds the test-mode flag values (see Listing 12.8). You could just as easily do the computation of the display string for the prices in the JSP code that needs to display it, but it's always a good idea to hide your business logic (including totaling ) in beans. Keeping the business logic in the beans also ensures that the calculation is always done right, lest someone forget to include taxes or shipping somewhere in the JSP. Listing 12.8 Cart.propertiestestTaxMode=yes testShippingMode=yes |
I l @ ve RuBoard |