Cure

 < Day Day Up > 



What if you have already written a lot of code and ignored what was available from other team members and external developers? Should you continue along this path, leaving your code as is? Let us look at why you might want to consider replacing existing code with external code, and what approach to take when doing so.

Sacred Code

Certain objects and various animals are revered in the many of the world’s religions and given special privilege and protection. These objects are shown great respect by the people of that religion, and are sometimes even protected by the laws of the lands in which the religion is practiced. However, the sacred code of programmers, or pieces of personal code that we protect with a religious fervor, does not deserve the same level of respect. Understandably, when we spend a considerable amount of time developing a piece of code we develop a certain attachment to it. This clouds our judgment and before we can consider refactoring code to use external libraries, we must overcome this prejudice. The best approach to obtaining a more objective look at whether your code has the merit you first ascribe to it is to seek out a third party, preferably someone not directly involved with the section of code in question. Have this person play the devil’s advocate and offer you an opportunity to defend your code. This allows you to come out reassured that your code is up to the challenge, or in some cases, you will come out with the realization that your code is not appropriate and should be replaced.

However, there lies a danger in ignoring the sacred code of programmers. Just as with many sacred objects of religion, many assume that the taboos associated with the object are illogical. Many see the believers in the religion suffering, yet refusing to break a taboo, and wonder what kind of insanity has possessed them. However, there is a meaningful explanation for this behavior. Many of these objects represent a source of practical usefulness. Some objects have uses to the people who worship them that are not immediately obvious. This is all overlooked by many outsiders because of the different culture and environment from which they come [Harris74]. Breaking the taboos of these religions would be disastrous, as would ignoring the sacred code of programmers without first understanding their purpose from the point of view of the developers who created them. The lesson to take away from all of this is that you should be wary of sacred code kept around for no valid reason, but be sure to query the programmer who is protecting the sacred code carefully to ensure that it is not just a case where you do not understand the reason.

When to Refactor

Once we are over our reticence, when should we consider replacing our own code with an external library or code snippet? To answer this, first consider when not to replace existing code. If the code is fully functional and thoroughly tested, you will not want to replace it with other code. Outside of this, there is room to consider third-party libraries on a case-by-case basis. Unfortunately, there are no set rules for determining when to perform this replacement. The best approach is to estimate the amount of time it will take you to complete the required extra functionality versus the time to integrate the library and replace existing functionality.

One advantage of refactoring that is often overlooked in this case is the long-term benefit of performing the refactoring. It is common to only consider the short-term benefits, but this can skew the results in favor of not refactoring. Therefore, it is a very good idea to look at the future functionality that is on the schedule and any functionality that has a good chance of being added or modified. By doing this, you might find that the library provides a better alternative to the current code for performing this future functionality. By performing the refactoring early, you will save development time as each of these tasks arises.

One Step at a Time

Once you have decided to switch out your code for new third-party code, you can begin refactoring. This refactoring must be performed at a slow and considered pace. Each basic unit of functionality that currently exists in your project should be replaced one at a time. After each swap, you must perform your automated tests to ensure that the functionality has not been changed by the new library calls. You should already have these tests in place; if not, now is a very good time to generate them. They must be in place before the code is changed. This makes it much easier to test for functionality changes because you can perform regression testing, which is done by comparing the results of tests performed before changing the code to those performed after. If the tests match, the chance that problems have been introduced by the change of libraries is greatly reduced.

If a test does fail, then your best approach is to locate the failed test and isolate the cause. If possible, this will allow you to reduce the code that exhibits the error to a smaller set of code. By doing this, you not only understand the problem better, you have a transferable example you can use to obtain help from your avenues of support. Be sure to verify that the library is at fault and not your own code. Have another programmer look at it if possible to gain objectivity. This also has several advantages, chief among them that you can provide the support resources with information on what you have already determined about the problem and what is not contributing to it. A second advantage is the good relations that you can build with support by not making them chase problems that you could have solved.

Conformance

Another important refactoring exercise to perform exists when you are using external code directly, rather than through a library. Because there is a wide variety of coding standards and approaches to problem solving, it is unlikely that code outside of your project will follow the same guidelines that you do. When you integrate libraries, this difference is isolated by the Bridge Pattern. However, when integrating code directly, such as with snippets of code, it is unlikely that creating a wrapper is necessary or even useful.

Instead, you should refactor the code to meet your coding standards. It is a good idea to integrate the code first before refactoring and ensure that it works, also giving you the opportunity to build the necessary test cases. Once integrated, you can begin refactoring the code one step at a time. Continuous testing ensures that functionality does not change. The new code will now be easier for other team members to understand and modify. Without this refactoring, each team member that had to interact with the code would have to work through the code style in order to determine what it was doing. This will cost development time, particularly if the code requires many changes across the course of the project. A side benefit of this process is a better understanding of the code that was just added to your project.

Workarounds

Another important consideration to take into account when using third-party libraries is how to handle problems and missing features in the libraries you are using. The first step to solving these problems is not to throw out the library. Instead, you should follow a set of steps that can allow you to continue to use the library and not lose all the work done so far.

You should start by verifying that you are using the library correctly. Carefully read the documentation related to the problem, and ensure that all reasonable variations have been tried. If you are then satisfied that the problem lies with the library, you should create a simplified version of the problem. This serves two purposes. The first purpose is to clarify the problem in your own mind so you can be sure nothing was missed. The second purpose is to provide a simple example that can be sent out for external support. Once you have constructed the example and confirmed that it suffers the same problem, send it out to all the technical support sources you have for the library. This might include the developers, message boards, and mailing lists. Be sure to explain what you want to accomplish, and ask if there is a current solution or, if not, a workaround.

While waiting for a response, you can consider your own workaround possibilities. Once you receive the response, take the proposed solutions from the responses and your own workaround solution and determine which is the best. If the solution ends up being a workaround, and not just something that you missed in the library, you need to take several more actions to reduce the future risks. First, implement the workaround with clear documentation. Preferably, a central list of workarounds should be available and read by all team members. This will allow you to easily locate and resolve any changes related to the workaround. Next, if possible, correspond with the developers and request that the problem be fixed in a future release. Even better, if you have full support you can request that an immediate fix be implemented. When the fix is available, you can remove the workaround to improve the robustness of the code.

Did We Mention the Importance of Testing?

If you have read the first two major illnesses, you understand how testing is important to preventing and curing those illnesses. Once again, testing is an essential part of handling NIH Syndrome properly. We already mentioned one of the important uses of testing when we discussed the best approach to performing any NIH Syndrome refactoring. There are two other contributions testing can make to reduce the risk of adopting third-party software.

First, tests allow for confidence in the event of switching libraries or changing to an internal implementation. A solid set of tests should be in place from the beginning of library integration. These tests should reflect the needs of the project, not the full capabilities of the library. If you go beyond the needs of the project, other libraries might fail the tests even if they are suitable for the tasks your project requires. With these tests in place, you can easily switch libraries and then run the tests to assure that the functionality remains identical. Without automated tests, the application must be tested by hand after such a large change. Manual testing is tedious and difficult, as well as prone to oversights.

Second, a form of development known as test-driven development is the basis for another technique that can assist in the evaluation of libraries’ suitability for your project. The basic idea is to write the test cases for the functionality required by the project. Ensure that all the important issues are tested. At this time, the tests will not even compile because the functionality is not there. You should also not look at any libraries or code that might be considered for providing the associated functionality. Next, write just enough for the tests to run and fail. This is important because you must test the tests for their validity. Once you are assured that the appropriate tests are in place, you can bring in the library you want to use for the desired functionality. As you integrate the library, you can check to see if each test passes and therefore confirm that the library is providing the expected functionality.



 < Day Day Up > 



Preventative Programming Techniques. Avoid and Correct Common Mistakes
Preventative Programming Techniques: Avoid and Correct Common Mistakes (Charles River Media Programming)
ISBN: 1584502576
EAN: 2147483647
Year: 2002
Pages: 121
Authors: Brian Hawkins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net