Ak5intoe




Sex: Male

Age: 44

Today's Date:
Oct 23, 2019 - 7:46 am

Viewing 1 entries.

YIM

Viewed 18907 times.

Add a Comment

Return to Web Site.

Recent Entries

Last 5 Entries

ALL Entries

Subscribe to RSS Feed



Archives
April 2007
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2930 




Home

Forums

Downloads

Patches

Donations

Online Store

Hall of Fame

Gallery

Server List

About Profiles

About the Game

Contact Us



LOGIN

Login

Forgot Password

Create A New Profile



Favorite Links


Hosted By
Hosted by OZNet

 
  Title: The Proper Care and Feeding of Software Applications
Apr 17, 2007 - 2:49 pm
Posted By: Ak5intoe


Introduction

I work for a very successful Fortune 500 Company. We have numerous applications that we develop and maintain. In particular I work on a product that brings in about 25 million a year. On a fairly regular basis I perform maintenance on the application. This mostly involves finding and fixing defects within the software. It always amazes me that given the state of the code the product makes the revenue it does. It?s been neglected for so long that many areas in the application require superhuman efforts just to maintain it.

I?ve spent a fair amount of time reflecting on why the code is in such a terrible state. Did the original developers not care or did they not know any better?  I?d like to think the source of the problem is the latter. Had they known better, I suspect they would have properly cared for the application. Yet, the past is what it is and the code is in the state that it is.

As a developer who does know better I find myself with a rather large predicament. I?m often tempted to jump in, make my fix, and jump back out without performing any sort of maintenance. I call this bungee maintenance. However, that won?t help the product, my team members, or the customers who use the product.

To solve the problems and to properly care for my application I need to be continuously refactoring. There are many articles and books that have been written on the subject. The goal of this paper is to discuss the most common type of problems I see in the code. I suspect they are the most common because they are the easiest to create and come naturally to new developers.

Unless you?ve been living in a cave you?ve heard the term, refactoring. In case you haven?t I?ll quickly define it. Refactoring is the process of rewriting code in order to improve its structure without changing its behavior.

Many of you may be refactoring today without realizing this is what you are doing. Have you ever looked at a method or class and thought, ?This could be written better,? and then actually changed the design of the code? If so, then you?ve refactored.

Code Smells

Before we go any further, it would be a good idea for another concept to be introduced. This concept is the ?code smell?. I think everyone has heard at least one time or another that a certain piece of code ?stinks?. Code smells now give us a means to describe why the code stinks.

Duplicate Code

The first smell we want to discuss is the duplicate code smell. This is probably the most common smell you will find in an application. You can probably guess what this smell is all about from the name. Any time there are duplicate sections of code in an application there is the potential of duplicate code smell.

Duplicate code is often the result of someone identifying a piece of functionality the software has in one location that the software now needs in another location. The quickest way to implement the change is to copy the code from location A to location B. The end result may be what the developer wanted, but now a problem has been introduced into the application.

Let?s assume the functionality that was copied contained a bug. It?s sometime later before the Quality & Analysis (QA) department finds and logs the bug. A developer is then assigned to fix the bug. The area in question is quickly found by following the steps laid out by the QA engineer and the developer fixes the bug. However, because there is another copy of the code, the bug was not fixed there. It will have to wait until that particular issue is identified once again.

On the other hand, maybe the code was perfect but now its functionality needs to be expanded. Once again, if the developer does not locate all sections of the duplicate code then a problem is introduced into the software. It won?t be long before someone points out the inconsistent behavior.

Fortunately for the developer, this smell normally has a simple solution. The toughest part normally is identifying the duplicate sections of code to begin with. While some sections may be exact copies, others may perform the same logic but go about it differently.

Once the duplicate sections have been identified the fix is usually just a matter of creating a method that does the same functionality as the copies of code. When that?s been accomplished the developer can then remove the duplicate sections and replace them with a call to the new method.

Example:
procedure CalculateTotalPrice;
begin
  price := price * quantity;
  totalPrice := formatFloat('$###.##', price/100);
end;

procedure CalculateTotalCost;
begin
  cost := cost * quantity;
  totalCost := formatFloat('$###.##', cost/100);
end;

We have two methods: CalculateTotalPrice and CalulateTotalCost. Both take an integer value, convert it to a float, and then format it as a string with a currency symbol.

While this particular example is small it works well to illustrate the point. Suppose the product is being introduced to Europe and rather than using the dollar sign you now have to use the symbol for the pound. Or perhaps the particular product is being expanded to support gas stations and the price and cost now needs to show 3 decimals instead of the two currently being shown.

We could solve the first problem by making the currency symbol a constant. However, we?ll ignore that solution and leave it the way it is.

First we need to create a new method that contains the duplicate code. I?ve called it CurrtoString


function CurrToString(value:integer): string;
begin
  result := formatFloat('?###.###', value/1000);
end;

Notice that both changes have been implemented in the new method. I?ve replaced the dollar sign with the pound and changed the formula to include three decimal points.

Next we need to replace the original sections of code with a call to the new method, CurrToString.

procedure CalculatePrice;
begin
  price := price * quantity;
  sPrice := CurrToString(price);
end;

procedure CalculateCost;
begin
  cost := cost * quantity;
  sCost := CurrToString(cost);
end;


There is now just one method that controls the converting of a currency field into its string representation. In the future, should something have to change, the developer only has to worry about the one method rather than possible copies that might be lurking about.

Long Method

The long method smell is also a common smell that exists in many software applications. This smell is often introduced when new functionality needs to be added to the software.

It goes something like this: There is a method that performs some sort of functionality. The project manager decides the application would better meet the needs of the customer if the functionality were extended. The assigned developer finds the method that performs the existing functionality and proceeds to add the new functionality. While in some cases this is appropriate, in many the developer is creating a long method.

This becomes a smell for several reasons. The first is that long methods are harder to debug. They often contain different levels of abstraction, which makes reading the code harder. They also tend to scroll off the screen which can become a problem if you can?t see the closing symbol for a particular block of code. Lastly, the method name becomes less descriptive of the process the method performs. Before the method name was DoSomething,  It now needs to be changed to DoSomethingAndSomethingElse.

To fix this the developer needs to look at the method and decide the proper course of action. This might be as simple as just extracting pieces of the long method and making a new method, or it might entail the creation of a new class or classes!

In our example DoSomethingAndSomethingElse, you can see that there is a conditional block that was added to the bottom of the method.

(In real life this method would be longer and probably more complex)
procedure DoSomeThingAndSomethingElse;
begin
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  if someCondition then
  begin
    ...
    ...
    ...
    ...
    ...
    ...
    ...
    ...
    end;
end;

In this particular example the fix is rather straightforward. At a minimum the code inside the added conditional block needs to be extracted into it?s own method. Then a call to that new method needs to be made from the DoSomeThingAndSomethingElse method.

As an alternative solution you may have put everything before the conditional block into its own method and the conditional block itself into a separate method. In this scenario our method DoSomeThingAndSomeThingElse now has two method calls.

procedure DoSomeThingAndSomeThingElse;
begin
  DoSomeThing;
  DoSomeThingElse;
end;

The goal here is to reduce the length of the method and maintain a consistent level of abstraction. Often times each instance of this smell will require a unique solution.

By keeping your methods short, free of conditional complexity, and containing the same level of abstraction you can ensure that your method will be easy to maintain and understand.

Summary

These two code smells are most common smells that I run across and they are the source of many defects. You may be asking how a long method, duplicate code, or any other smell is the source of a defect. The code itself may be perfect and runs just fine, so how can it cause problems? The problem is that it increases the complexity of the code. It makes it harder to figure out what?s going on and therefore it creates an environment in which it?s easy to introduce defects.

We only covered two particular smells. There are many, many more. You should train yourself to identify them all. You should also know how to solve each one. Only then will the software you write maintain the elegance and style that it was created with.

Resources:

If you?re looking for more smells you can find some lists here:
http://c2.com/cgi/wiki?CodeSmell
http://en.wikipedia.org/wiki/Code_smell
http://www.codinghorror.com/blog/archives/000589.html

There are also some great books out there that discuss in depth some of the complex smells and the solutions needed to fix them.
?Refactoring To Patterns? by Joshua Kerievsky
?Refactoring? by Martin Fowler




2003-2004 by the Alien Assault Traders developers. All rights reserved.