Kirk is a software developer who has filled most roles on the software developer team. He is the author of Java Design: Objects, UML, and Process (Addison-Wesley, 2002) and he contributed to No Fluff Just Stuff 2006 Anthology (Pragmatic Bookshelf, 2006). His most recent book, Java Application Architecture: Modularity Patterns with Examples Using OSGi was published in 2012. Kirk is a DZone Zone Leader and has posted 77 posts at DZone. You can read more from them at their website. View Full User Profile

Source Code is a Corporate Asset

07.01.2009
| 4887 views |
  • submit to reddit
The goal of software development is to - SURPRISE! - deliver software. Fancy architecture diagrams, detailed requirements documentation, and comprehensive project plans mean little if we can’t deliver the software that realizes them.

The source code is the detailed specification for a software system, and it is the only specification guaranteed to offer an accurate representation of the system. It is also the only artifact we must create in order to deliver a software system. Assuming an organization views the software system as an asset, then so too is the source code. Source code is a corporate asset that must be carefully guarded!

Guarding the Source

High quality source code is important. A malleable codebase is easier to change, eases maintenace, and speeds delivery. An organization may have a mature change management policy in place, but an application that resists change due to mangled source or architectural inflexibility cannot be modified and delivered quickly. A fully tested codebase is also important. Tests allow us to verify correctness, identify defects, and lend us the courage to make change by providing a safety net to identify the ripple affect of change. Finally, a functional codebase is important. A codebase that is void of compile and test errors can be frequently delivered, allowing us to garner important customer feedback that helps ensure we never stray far from our intended destination.

In other words, if we develop a codebase that is malleable, fully tested, and functionally complete, our team possesses the ability to continuously deliver software in the face of change. By emphasizing creation, growth, verification, and deployment of our code from initial project inception to final solution delivery, we are developing an inherently agile software development environment. At the center of this process is the source code, and we would do well to guard this source code with artifacts that help move it along this path. Ideally, these artifacts are executable.

Executable Artifacts & Fidelity

The traditional software lifecycle consists of high level activities, each producing an artifact fed into subsequent phases. These artifacts are interpreted by humans and manually translated into some other software artifact. Eventually, we get to the source code. This approach lacks fidelity, and valuable information is lost during each translation. It’s a bit like Chinese Whispers, and is fraught with cumulative error and inaccuracies.

Executable artifacts guarantee fidelity. If an artifact ever becomes dated and out of sync with the source code, the artifact breaks. Executable artifacts offer a real-time up-to-date glimpse into the application development effort. Executable artifacts guard the source code in a variety of different ways. Executable artifacts also help increase project transparency.  Here are some other advantages of executable artifacts:

  • They are an accurate reflection of the code at the point they were run. For most teams, ensuring documentation stays synchronized with the codebase is a daunting task. Because executable artifacts are run against the source code, we can always be certain that they reflect the current state of the source.
  • They can be run at any time, with little overhead. After initial setup of the executable artifact, they can be easily run against the source code, usually by issuing a simple command.
  • They encourage early and frequent delivery. Since we have a functional codebase, we can garner important feedback throughout the development lifecycle.
  • They can be automated. Automating an executable artifact means little manual intervention is required. Additionally, automation reduces the likelihood of errors or omissions that is common with manual processes.
  • They maintain a reliable history. An executable artifact, run at frequent and regular intervals, produces output that can be analyzed over time to help the team identify trends in development.

 

Let’s consider a simple development scenario

The Development Scenario

As a project commences, the development team meets with the customer to elicit high level requirements. In lieu of producing a detailed software requirements specification and obtaining signoff from the customer before moving onto development, the development team adopts a strategy to deliver running tested software on a frequent basis. A business analyst develops a suite of acceptance tests using a tool such as Fitnesse or Selenium. Simultaneously, the developers create an automated and repeatable build process scheduled to run hourly. Incorporating execution of the acceptance tests into the build process ensures that the application always satisfies the current set of acceptance tests, which serve as a set of executable requirements for the application development effort.

The priority of the development team is to ensure the application always remains in a functional state by passing all acceptance tests. Because the application is always functional, the development team can deliver the software into the hands of the customer on a frequent basis. As a stop gap to ensure they maintain a high degree of customer feedback, the development team hosts regular application demonstrations for their customers.  As customers participate in these demonstrations or interact with the application, the feedback they offer can be managed via an issues backlog that is a valuable input artifact to subsequent iteration planning sessions. As change trickles in and new features are identified, additional acceptance tests are added to the suite.

To ensure the application architecture maintains a high degree of resiliency and adaptability, the team places constant focus on growing their unit test suite and makes certain all unit tests are executed as part of the build process. By ensuring unit tests verify classes and methods in isolation from outside forces, application components are naturally decoupled. To further enhance application architecture, the development team generates a number of software artifacts as part of the build process. Class and component diagrams in conjunction with dependency metrics offer valuable feedback that lead the development team to targeted refactoring efforts to maintain a high degree of architectural and design resiliency.

Eventually, the build process updates a project dashboard that includes important project metrics, including the number of tested teatures supported in the current software build. All project participants, including the software development team, customer team, and management team, have access to the project dashboard via a URL, ensuring the team always knows the current state of the application. The consistency and repeatability of this micro process allows the team to identify important trends in development, such as development velocity in terms of the number of tested features delivered. They are able to develop burn down charts, backed by evidence, that help the team provide more reliable estimates based on historical evidence.

In this development scenario, executable artifacts serve as a powerful catalyst for other important practices, and enable another key aspect of frequent delivery. Because artifacts are executable, they can be automated. But at the center is software development’s most important artifact - the source code. Once a team begins guarding the source with executable artifacts, a vicious, self-generating, and remarkably powerful process emerges.

As you consider embarking on a software process improvement initiative, begin planning your agile transition, or simply kick-off your next project, reflect for a moment on the ultimate goal. The purpose of any software development effort is software delivery, not software process improvement, documenting requirements, or creating architecture documents. The only artifact required to deliver software is the source code, and all artifacts should feed this requirement. It’s imperative that we treat source code as a corporate asset, and guard it as closely as possible. While other artifacts are inevitably necessary, executable artifacts guarantee fidelity with the source code, and can prove its quality, resiliency and functionality.

From http://techdistrict.kirkk.com/

Published at DZone with permission of its author, Kirk Knoernschild.
Tags:

Comments

Piotr Kochanski replied on Thu, 2009/07/02 - 2:24am

"The source code is the detailed specification for a software system, and it is the only specification guaranteed to offer an accurate representation of the system" - this is common misconception spread by people, who are advocating agile methodologies.

The code which is calculating sine function does not say what is sine function. If I don't have "specification" of sine function, only the code, I have a very limited knowladge about properties of sine function. Imagine that suddenly my application starts working incorrectly due to approximations used to calculate sine, how can I correct this code if only thing I know is that this code is a sine function?

If I use in my application sine squared and somewhere else I need to use cosine squared then without specyfication I will be wasting processor time calculating cosine squared instead of substracting 1 - sine squared.

Specyfication says what the application is supposed to do, the code says how it is done. These are two different things and both are important.

It is hard do imagine building any financial application without taking into account all issues connected with law regulations (think of rules concering rounding monetary values - there are more or less eight different approaches), security requirements, etc things which are often totally alien to average developer. Without specification such software cannot be built.

Obviously the hard task is to maintain in sync the code and the specification. It costs money, but has to be done, that's why the cost and time of coding in the software project is usually smaller then all other tasks needed to deliver software.

Andrew McVeigh replied on Thu, 2009/07/02 - 10:45am in response to: Piotr Kochanski

the code which is calculating sine function does not say what is sine function

 

it's a very, very good point, and it is astonishing to me to see that someone is advocating that the source code represents the specification of a problem.  it's confusing "how with what".

in studying formal methods (which are required for a number of mission critical applications such as fly-by-wire and some medical fields) the most obvious and simple example of the difference i've seen is with the square root function.

spec: x is the square root of y if x*x == y

how: many ways from the simple (newton-raphson) to complex bitwise manipulations.

Andrew

Stephane Vaucher replied on Sun, 2009/07/05 - 9:14am in response to: Andrew McVeigh

Not sure about code being the specification of the problem, but I believe experts in reverse engineering talk about the specification of the solution. For many maintenance tasks, properly understanding how the problem is being solved is more useful than how it should be solved (especially when we wrap then interface with legacy components). Stephane Vaucher

Andrew McVeigh replied on Mon, 2009/07/06 - 11:30am in response to: Stephane Vaucher

Not sure about code being the specification of the problem, but I believe experts in reverse engineering talk about the specification of the solution.

I guess so.  That would make sense, if understanding the existing code were the problem to be solved, as per your reverse engineering example.

the problem i have with talk of code being specification, is that a specification says what rather than how, and omits the detail.  code by definition must have enough detail to be executable.

Mike Toth replied on Tue, 2009/07/07 - 3:58pm

This appears to be a semantic argument which hinges on the definition of "specification" and "code".

"Code" appears to refer to language that is human manageable and machine executable. As a language, it contains symbols that map to some conceptual model- as a machine executable language, the mapping is precise, deterministic, and unambiguous.

"Specification" is somewhat interesting here. It also refers to a language expressed against some conceptual model, but the general implication is that there is some detail missing. The nature of the missing detail is key to the discussion.

Sometimes the missing detail is the mapping from the conceptual model of the specification to the conceptual model of the implementation. The wider the gap, the more human effort is required to bridge it and the less the "code" resembles the "specification"- ie. the mapping between the specification and code becomes very complex. Consider writing a GUI/database application in assembly language, as an extreme example.

The above type of missing detail underlies the "implement a sine function" problem, which normally would appear when implementing a language (or a library) that provides a conceptual model of math operations.

Sometimes the missing details are simply those that are not considered important by the person creating the specification. This missing detail may be filled in creatively by a designer. In a system where the same conceptual model is used by both the specification language and the code language, these missing details may be filled in by default.

In other cases, missing detail in the specification may represent an issue in the requirements gathering process, which may not be uncovered until the specification is transformed into code.

There are applications where ideally, the "specification" is -part- of the "code". Because it is useful to have the specification expressed in some precise language, a "problem domain modeling language" can be a good way to capture the details of the specification. The language implementation is then responsible for transforming (ie. compiling, interpreting, mapping, generating, etc.) this model and behaving appropriately.

What it comes down to is the difference between the outputs of the requirements, design, and coding process. We have  "requirements specifications" and "design specifications". Depending on the application and the customer and the amount of conceptual distance that needs to be bridged, many scenarios may benefit from running the requirements, design and coding process in parallel such that the output of the chain is always code, with no intermediate "documentation" to be maintained. I would imagine that such code would be in a very high level, human readable form- perhaps a declarative language or a data structure- with lots of room for textual annotation. 

 

 

Andrew McVeigh replied on Wed, 2009/07/15 - 6:30am in response to: Mike Toth

>The nature of the missing detail is key to the discussion.

with a specification, the missing detail is usually "how".  the specification says what is needed.  the how can range from being trivial (e.g. how a text field updates a database row) to the complex (how to solve a complex mathematical function).

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.