The bug went something like this:
A bunch of client code called a particular method, which took two type codes. For the sake of example, we'll say that they represented, respectively, different meats and different vegetables. The method was intended to construct a balanced Meal object.
public Meal makeBalancedMeal(int vegCode, int meatCode) ...At some point, the method gained an alternate, improved signature, and the old signature was deprecated and eventually removed. The new signature was this:
public Meal makeBalancedMeal(Vegetable veg, Meat, meat)...This was an awesome step forward. It has the advantages of:
During the refactoring, the writers of the client code realized that they had a lot of calls to the original method signature and they became intimidated. To use the new call, they would have to change a lot of lines of code to pass the new types. Because they had already wrapped the call with a "utility" method:
public static Meal getMealWithoutWashingHands( int vegCode, int meatCode)Inside this method, they created Vegetable and Meat objects and passed them to the newly refactored makeBalancedMeal object. The problem is that they screwed it up:
public static Meal getMealWithoutWashingHands( int vegCode, int meatCode)Reversing the codes wasn't always a problem. Sometimes it created a perfectly valid combination. Other times, though it broke horribly. Not surprisingly, hilarity ensued.
{
Vegetable veg = new Vegetable(meatCode);
Meat meat = new Meat(vegetableCode);
return makeBalancedMeal(veg, meat);
}
Had they stuck with passing the typed objects, they could not have had this problem. They might have made the mistake elsewhere (at some point, you do have to deal with the int values), but they wouldn't have made it here, in new and relatively untested code.
Why did this come about? I blame the system. As usual, there is the institutional fear of refactoring as "introducing too much change and creating bugs". In fact, done sanely, it prevents bugs. The developers who knew that changing from Type Code to Class was a good idea had been beaten down by management to not do anything so bold on a large scale. Instead, they ducked the issue and added yet more code to do exactly the same broken thing.
As might be expected, the results were horrible. The code produced meals such as "Chicken Neck and Radishes" and "Beef Tongue and Jicama". This caused issues with actual customers in production, costing the company Real Money.
0 comments:
Post a Comment