Prevention

 < Day Day Up > 



Hardcoding often appears to be the easier and faster method to implementing code that requires numbers or strings. The first step to preventing hardcoding is to realize that this is an illusion, and more often than not it will cost you time down the road. Nonetheless, this might not be enough to overcome the temptation if there is not a convenient method for moving the value to an external file. Therefore, to further decrease the likelihood of hardcoding, we must examine methods to assist in creating and managing external sources for the values that would otherwise be hardcoded.

Standard Data Source

The first step to assisting in removing hardcoded values is to establish a standard location for each type of data. For example, strings that are to be localized are stored in a single file or a group of files separated under a single directory. The file or files generally contain matching label and string pairs. When localization is required, the translator only needs to go to the file or files and change the string values in each pair. This provides a clear advantage to the translator, but does it assist the programmer? The programmer also now has a central location where he can add new strings as needed, and at the end of the project the programmer will not have to go scrounging around to find all the strings that need to be translated. Hence, both the translator and the programmer save time in the long term, even if there is an extra bit of work in the short term.

Not surprisingly, most strings that are to be localized will appear in the user interface. This is true of a large number of values that would otherwise be hardcoded. Placing user interface values outside of the code allows the visual appearance of the application to be tweaked without recompiling. This becomes especially important on large projects with slow build times. It is common to find tools for creating user interface layouts that allow easier manipulation of these external values, but the values are still likely to be external. If you do encounter a user interface builder that places the values directly in the code, be careful, as this is not quite as clean and can slow the testing and refinement process. Occasionally you will encounter user interface components that can be edited while the application is running. This is the best scenario to have during development as it greatly increases the speed of value tweaking, which can be a tedious and time-consuming operation even in the best circumstances.

Both the user interface values and other global application settings are best stored in external configuration files that are, at least during development, text based. This allows easy debugging and sanity checking when necessary. While you can safely convert these files to binary at the end of development, it is an unsafe approach to use the binary files during development except when necessary. Using binary files causes reliance on the tools and programs that edit and convert the binary files. This becomes another failure point that is harder to debug without easy-to-read asset files.

Notice that we have talked primarily about configuration values. These values are susceptible to hardcoding, and this is what we want to avoid. Other forms of data that the application is created to manipulate do not fall under this temptation because that data does not exist as a single value. It is unreasonable to hardcode values when you cannot predict what they will be, thus making these values safe from the dangers of this illness.

XML

Modification and debugging of external values can be made easier by maintaining only a small set of file formats. While you might not be in control of all the file formats in use, due to the tools and third-party libraries used, you should strive to maintain consistency across the file formats that are under your control. This means less syntax to learn for all the programmers on the team, and fewer parsers to debug when things go wrong.

We have already mentioned the benefits of text because it can be read by a human for debugging what the application and data editors are doing. There is a further advantage, which is the availability of already written text parsers. This can be taken one step further by using XML, which provides a standard data format that is being widely adopted across the computer industry. By using XML, you immediately add a large number of tools and software technologies that can be used to assist in development.

 CD-ROM  XML is used extensively by many new technologies such as .NET and the Apache Ant build tool for Java. The build file for all the Java examples in Source/JavaExamples/build.xml on the companion CD-ROM provides an excellent example of XML in practical use:

<?xml version="1.0"?> <!-- Build file for examples from Preventative Programming Techniques --> <project name="Prevention" basedir="." default="all">    <!-- Import system environment variables. -->       <property environment="env"/>    <!-- Define common properties used throughout build file. -->     <property name="jarfile" value="PreventionEx.jar"/>     <property name="manifest" value="MANIFEST.mf"/>       <!-- Compile the examples using the AspectJ compiler. --> <target name="compile">            <taskdef name="ajc" classname=" org.aspectj.tools.ant.taskdefs.Ajc "/> <ajc source="1.4" srcdir="." destdir="." debug="true" deprecation="true"/> </target>    <!-- Package the compiled examples in a compressed jar file. --> <target name="jar" depends="compile"> <jar jarfile="${jarfile}" manifest="${manifest}" compress="true" basedir="."> <exclude name="build.xml"/> <exclude name="**/.nbattrs"/> <exclude name="**/*.java"/> <exclude name="**/*.form"/> <exclude name="${manifest}"/> <exclude name="${jarfile}"/> <exclude name="apidoc"/> </jar> </target> <!-- Perform the most common build functions. --> <target name="all" depends="jar" description="Build everything."> </target> <!-- Run a test of the examples after compiling them. --> <target name="test" depends="all" description="Test examples."> <java classname= "com.crm.ppt.examples.Main" fork="true" failonerror="true"> <classpath> <pathelement location="."/> <pathelement location= "${env.AJHOME}\lib\aspectjrt.jar" /> </classpath> </java> </target> <!-- Generate documentation from comments. --> <target name="javadoc" description="Javadoc for Prevention."> <mkdir dir="apidoc"/> <taskdef name="ajdoc" classname=" org.aspectj.tools.ant.taskdefs.Ajdoc "/> <ajdoc packagenames="com.crm.ppt.examples.*" destdir="apidoc"> <sourcepath> <pathelement location="."/> </sourcepath> </ajdoc> </target> <!-- Delete generated files. --> <target name="clean" description="Clean all build products."> <delete> <fileset dir="."> <include name="**/*.class"/> </fileset> </delete> <delete file="${jarfile}"/> <delete dir="apidoc"/> </target> </project>

Further examples of the extensive use of XML can be found from Integrated Development Environment (IDE) products such as IntelliJ’s IDEA to asset files for games. In particular, XML lends itself to storing any type of hierarchical data that can easily be represented in text format. It is also designed with the ability to read and process the XML file from a stream if the data is structured appropriately, which is important for many applications including Web-based applications.

In addition to the many editors, such as XMLSpy (Figure 8.1), that are available to edit XML, other technologies improve the usefulness of XML. One important addition is XML Schema that defines rules for the structure of a particular data file. When moving from hardcoded values that can only be changed by programmers to external files editable by other developers, the loss of control can make it easier for errors to be introduced into the data. By providing appropriate XML Schema, errors can be tested for while editing the file without the need to build complex validation code into your application. It is interesting to note that XML Schema are stored in the XML format as well, allowing them to be edited in the same manner as the other XML files that they will be checking.

click to expand
Figure 8.1: Ant build file shown in XMLSpy for viewing and editing.

The extensibility of XML and the wide array of tools available make it an excellent choice for a wide range of data storage, but be careful not to become enthralled with the virtues and ignore simpler solutions when appropriate. Sometimes all that is needed is a configuration file containing name and value pairs, and XML only reduces the readability. Evaluate your needs and then you can conclude whether XML is the right choice for the particular job you have in mind.

Asset Management

Another important consideration in easing the process of avoiding hardcoded values is management of the resulting assets. Updating and accessing these assets must be seamless if a programmer is expected to add values to them on a regular basis. Any hindrance will increase the likelihood that temptation will win over and the easy route of hardcoding will be taken.

Of primary importance is allowing the simultaneous access and modification of the asset files by multiple programmers. This requires two major components, the first of which is a source control system that supports merging of files edited by more than one programmer at the same time. This presents another important reason for using text files as the basis for these assets, because merging binary files is not a feature that you can expect your source control system to support. Even after a source control system is in place that supports merging, the file format must be such that merging is as unambiguous as possible. Distinct tags can help with this process by preventing matches from occurring by mistake, and XML represents an excellent choice for providing these tags.

Another consideration is the addition and removal of information from the asset files. This must often be synchronized with the changes to source code. Some effort should be made to maintain backward compatibility and version information, but this must be balanced with the need to move forward. Without the backward compatibility testing, failures that occur outside of a single build become problematic. Whether this is possible and whether it is worth the effort must be considered on a case-by-case basis. When backward compatibility is not possible, it is beneficial to have a source control system that supports the submission of multiple files at once to maintain a consistently working build. This is also a reason to avoid partial code submissions to the source control database when possible. It is easy to overlook dependencies between files that are submitted and those that are not. When you must submit only part of the code and assets you are working on, be careful to review what changes were made and look for any missed connections.

Finally, it is beneficial to have an organization to the assets that is easy to understand and extend. This includes directory hierarchy and file naming conventions. Add this to the other asset management concerns not related to the hardcoding and you will often find that asset management can be a full-time job. The amount of time required is an important consideration in scheduling and resource management that should not be overlooked.



 < 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