One of my clients decided to
reorganize their portfolio of applications to reduce the duplication and
complexity in their systems. As part of this process they decided to try to
deliver the majority of their system via a Web front end to their internal user
community, who were all using Internet Explorer 5.5+ as their Web browser.

A range of components

As with any set of
developments in a common area, we quickly came across a variety of functions
which were reused from project to project. These components encompassed a range
of technologies including .Net, JavaScript, CSS, Classic ASP, and XML. The
items themselves were equally wide ranging, for example DHTML menu controls, regular
expression validator functions, common CSS classes, and
a classic ASP XML reader which used .Net’s Web.Config
file alongside the .Net components included in the system.

Over time, these functions,
components and scripts were packaged up into a set of common items, with names
such as common.js or common.css, and moved from project to
project, system to system. As the reuse increased, some instances of the functions
were enhanced, bugs were fixed etc, and we were faced with the problem of
pushing this change out to all copies of the specific function within our
complex infrastructure.

At this point, the development
architecture team began to look at the best way of leveraging and managing the
use and growth of these items within the organization. After much discussion,
we were able to divide the code into four distinct groupings:

  1. Corporate
  2. Application Global
  3. Component / Subsystem Global
  4. Page specific

Items in the first case were
functions, CSS Classes, images and the like that were used on the majority of Web
based applications. This included the CSS and images that were used for our
common corporate look and feel as well as an ASP.Net
menu system and some JavaScript functions such as isInteger and addOptionToDropdown.
Items in the second set were primarily specific to a given Application
within our portfolio such as a function that validates bar codes for our data
entry system or an application specific logo.


Downloadable version

A downloadable version of
this article is available in PDF form from the TechRepublic
Download Center.


The third set were items
that were part of either a component such as a DataGrid or part of a subsystem
that were not required to be available to the rest of the application, such as
a login control or a stored procedure to create users in a given system. The
final set were items that were implemented on an almost once off page level
such as specific CSS styles or validatory JavaScript.

Now that we had identified
the four groupings that we wanted to segregate our code into, we began looking
through the code were working on to align the functions, classes etc. with this
new structure. A new set of prefixes were added to our coding standards to
identify to which group each element belonged to. Slowly, each application
began to include a corporate package and an application package in addition to
their own specific functionality. By “package,” I mean an external
JavaScript and CSS file as well as new sections in the Web.Config files for .Net applications and their equivalents in
other languages such as classic ASP or J2EE.

It was decided that all
corporate elements should reside on a single central server to ease management.
To support ease of management across all systems, the directory structure shown
in Figure A was introduced for the
first two groups.

Figure A

Directory Structure

While the content of the CSS
and JavaScript directories should be obvious, the other entries require a
little more explanation. The Config directory contained configuration files
that were needed by the code in that group. These included .Net’s Web.Config files and classic ASP’s .INC type, as well as the traditional .INI file types. The Scripts directory
contained any interpreted scripts present at that level such as classic ASP,
PHP or Perl as well as other files such as batch files. The final folder—Bin—contained
compiled code such as ASP.Net applications, ActiveX DLL’s and Java Servlets.
Within each folder, further sub folders allowed greater management of the
individual elements.


Additional white paper resources

“Patterns
& Practices Live: Writing Optimized Managed Code”

“An
Overview of Managed/Unmanaged Code Interoperability”

“Writing
Managed Code in Visual Studio.NET”


For each folder in each tier
a custodian was appointed to be
responsible for the management of the items in the specific folder. This role
included being the key contact for the items as well as being the lead contact
when they were updated whether it was for a bug fix, routine update or
functionality enhancement. They are also responsible for ensuring that adequate
documentation existed both within the code and separately and for the
management of those items—for example backup and storage in a source code control
system.

This level of enhanced
symbiosis of the code between systems forced a greater level of documentation
and quality control upon the developers and the custodians of the content of each tier to ensure that any work done
on an existing function—such as adding a parameter—or any new functionality
added, did not cause major problems for other systems that also used the same
function.

On the JavaScript and CSS
front, this made the management of the organization-wide code base easier as
functions could be moved from one tier to another with minimum effort as the
situations required them. The move would require a cursory test of the affected
systems to ensure that there was no impact. Therefore, a JavaScript function
that began life at the application level could easily be moved to the corporate
level once it had been reused repeatedly simply by copying and pasting the
file.

Reducing lines of code

With this rationing of the
way the development team worked—the segregation of individual code elements,
CSS Class, images etc., and the use of custodians—we
have been able to significantly reduce the number of lines of code that are
written for each application. Also, the increased use of packaged functionality
means that less time is required for testing, QA and documentation as the
functionality has already been proven to work.

This efficiency saving has
been reflected in the work estimates that we have been able to give to our end
users. In this case, a fair amount of effort up front has resulted in major
cost, resource, and time saving for the organization and the rewards are being
reaped by subsequent projects.