1. Home
  2. Tutorials
  3. Software Productization
Yolinux.com logo

Software Productization: Software Architecture and Design for Productization:

Description of software architecture, design and concepts to support software "productization".

"Productization" and reasons to avoid forked code:

Productization is the process of converting software for re-use into a product others will find useful whether it is for the retail customer or by another group internal to a company. Even when there is no customer or end user, the architectures and principals employed are good coding practices which help its own development and maintenance and also reduce costs.

Some of the easily recognizable features of productized code are:
  • Easy to install.
  • Easy to configure.
  • Easy to use. Simple navigation. Intuitive interface.
  • Use of standards:
    • Coding standards.
    • File format standards.
    • Interface standards.
  • Consistant logic and methodology.

Software written for a single and specific purpose and use may not require flexibility or configurability. The software can be specifically written to fulfill the design requirements while ignoring modern design styles and practices. Much software is written this way, (especially prototype code) with hard coded values and rigid logic. Good software practices are often ignored to shorten initial development time. This of course sets the stage for trouble if flexibility is required later (and it almost always is).

When a new project with similar requirements as an existing project needs software, it may use the existing project as it's starting baseline and fork a new version for a new purpose. As these source code forks multiply, the bug fixes rarely make their way back into all forked versions of the software with the same bug. Enhancements to one version rarely make their way back into the other versions and if they do, they require N refactory changes for all N versions. The merging of changes becomes more difficult as each new version becomes unique and the bug fix or change will thus integrate differently for each version.

It shocks me how prevalent the forking and replication of code has become with major corporations and with large software applications. The excuses often point back to code ownership, lack of inter-division or inter-project communication or security rules which restrict communication between programs. It is almost standard procedure at defense contractors to fork the code base as there is no budget allocated for the redesign of working code nor is there budget allocated to have different programs cooperate and leverage existing assets. The scope of authority of program managers is usually restricted to their own program.

Diagram: cloned and forked software

Alternatively, software written as a product to be sold to multiple customers or written to be used for more than one application is typically configurable to some extent, so that each user/customer/corporation can use a singe version of software for the purposes at hand.

Now I would like to introduce the concept of "Productization". The larger the code base, the more important and critical the concept becomes. At the first sign of change, the code should NOT be forked or duplicated for a new code base. The changes need to be introduced so that the software performs both tasks, the old and new. Command line arguments and options, configuration files (XML: C++ or Java), GUI input and plug-ins are all established concepts which allow a single piece of software to operate in a custom manner based on the purpose assigned by the user. Could you imagine the number of versions of the UNIX sort command which would exist if the command line options were not available. C preprocessor #defines and choices of header files can also be used, but this is the last choice as it results in multiple and different executables. The C preprocessor directives are perfectly acceptable when supporting multiple hardware architectures as target compilation is required. One should accommodate multiple operating systems by using cross platform API's where possible. (i.e. GTK, STL) Platform specific API's should be encapsulated in as few interfaces as possible thus allowing for a simple substitution of interface classes or use of a compiler directive to use a different library.

The software should be architected so that values are not hard coded but specified by the command line or configuration file. Often programmers extract constants from the code and place it in header files as preprocessor macros or parameter statements. This is not enough. The values should be pulled out completely, into a configuration file for more flexibility. Flexibility of logic choice can be specified by Boolean values also specified by the command line or configuration file. The core software should be generic in design to allow this flexibility. The software design should then provide an API to interface with this core product. The API will allow the creation of custom products where only the specifics of the task are written. This avoids the duplication and existence of cloned forks which are created when the core is repeatedly copied when an entire project is forked for a new purpose. Duplicated code duplicates bugs and linearly scales the maintenance effort.

The maintenance and development of a "productized" software application requires that the needs of the most sophisticated target applications should be included in the "core" product, and not just that used and shared by all, including the less sophisticated target applications. If the "core" is limited to only the common components shared by all, the product ends up with too much duplicated code on the outer layer using the API and the problem repeats itself. Common functionalities should be isolated into libraries (shared components). Good OOP (Object Oriented Programming) design will also support component re-use.

Software architectures which support "productization" well include:

  • GUI programs: A user extensible GUI with user supplied call-backs.
  • Applications which focus on process flow: Polymorphic relationship between the application core and user defined functionality. The core application framework calls base class pointers to enforce the process flow structure while the user defines functionality in derived class functions. Virtual function definitions in the base class definition enforce the structure of the software design.
  • Plug-in architecture: Plug-ins which are added by the application as loadable libraries (C/C++ libdl, Java OSGi), allow third parties to add features to the product by conforming to a defined interface. This provides flexible modularity which does not have to be compiled into the final executable. (See YoLinux Tutorial on Libraries and loadable modules - C/C++.)
  • Distributed processes or Service Oriented Architecture (SOA): A core set of processes or services can be extended by offering new processes or additional services to the collective system. The above architectures can be employed to extend an individual process or service. The system API can be regarded as the interface to a process or service.

The "productization" of the software application will result in a configurable application built upon a programming framework.

Software architecture for productization

The benefits of "productiztion" of software are:

  1. Bug fixes and enhancements made to the "core" software benefit all derived applications.
  2. Lower total cost of software development.
  3. A common code base is used by more developers and thus more bugs are discovered and fixed.
  4. More developers work on the "core" code and thus improvements and rework are compared and shared.
  5. Speedier development of new applications using an application framework or by reconfiguration.
  6. Fewer programmers required for code maintenance and bug fixes due to a smaller code base.

In short, the software will have fewer bugs, less money is spent on development, allot less money is spent on maintenance and more capability becomes available in the final application.

"Productization" is a concept which should be invoked early to avoid the first cloned fork of code. It must be introduced to save some of the projects from an uncontrollable explosion of the size of its corporate code base. Too often management looks only at the single project without looking at the cost savings to the corporate entity.

Book imageBooks:

Beyond Software Architecture: Creating and Sustaining Winning Solutions
Luke Hohmann
ISBN #0201775948, Addison Wesley Professional; 1st edition