Skip to content

About

2007 example: refactoring procedural JavaScript to OOP with recursive nested configuration

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nested System Configurator

In late 2007, I worked on a major overhaul of a system configurator for a hardware e-commerce platform. The previous implementation had a significant limitation: when configuring a rack or cluster of servers, users could only select from a list of preconfigured server options. This was frustrating for customers who needed to customize individual servers within their cluster configuration.

The goal was to enable full configuration of each server type in a cluster, allowing users to customize CPU, RAM, storage, networking, and other options for each server individually, while maintaining real-time price calculation and slot/rack space management. This refactoring transformed a procedural JavaScript configurator into an object-oriented system that supports nested, fully-configurable subitems.

This repository shows how a JavaScript system configurator component evolved from a procedural architecture with global state to an object-oriented design that enables recursive configuration of nested components. This was during the period when JavaScript was transitioning from purely procedural scripting to object-oriented programming, and the architectural patterns shown here reflect the kind of thinking that was emerging at that time.

The code here is original implementation created for educational purposes that demonstrates the same architectural patterns and design decisions as the original work, without including any copyrighted code. This approach allows us to study and learn from the architectural evolution without copyright concerns.

📊 Architecture Comparison

Before (Procedural)

  • Global variables for state
  • Monolithic 200+ line functions
  • Simple price objects for subitems
  • No recursion support
  • State scattered across DOM and globals

After (Object-Oriented)

  • Encapsulated state in objects
  • Modular methods with single responsibilities
  • Full configurator instances as subitems
  • Recursive price calculation
  • Clean separation of concerns

Interactive Demo

Try the configurator in your browser. If you have this repository locally, you can also open index.html directly in your browser.

🔍 Key Concepts Demonstrated

1. Recursive Configuration

The key insight: allowing subitems to be full configurator instances rather than simple price objects. This enables:

  • Each component in a system to have its own full configuration
  • Real-time price calculation that recursively includes all subitem prices
  • Independent warranty calculations per subitem
  • Slot/space management that tracks usage across all subitems

2. Polymorphic Design

Both configurable items and simple components implement the same getPrice() interface, enabling polymorphic price calculation.

3. Encapsulated State

All configuration state lives within object instances, not scattered across global variables or DOM elements.

Implementation

The core innovation is the recursive structure. Here's how getPrice() works:

class SystemConfigurator {
    getPrice() {
        let price = this.basePrice;
        
        // Add option prices
        this.options.forEach(option => {
            if (option.selected) {
                price += option.price * option.quantity;
            }
        });
        
        // Recursively add subitem prices
        this.subitems.forEach(subitem => {
            // Polymorphic call - works for both Configurator and SimpleItem
            price += subitem.getPrice() * subitem.quantity;
        });
        
        // Add warranty
        price += this.getWarrantyPrice();
        
        return price;
    }
}

Because subitems can be full SystemConfigurator instances themselves, the recursive call naturally handles nested structures of any depth.

Example: Nested Cluster Configuration

Here's how this works in practice with a cluster configuration:

Cluster Configuration (SystemConfigurator)
│
├─► Base Options: Cluster Management Software
│
├─► Head Node (SystemConfigurator subitem)
│   ├─► CPU: Option B
│   ├─► RAM: Option B
│   └─► Warranty: Standard
│
├─► Compute Node 1 (SystemConfigurator subitem)
│   ├─► CPU: Option A
│   └─► Warranty: Standard
│
├─► Compute Node 2 (SystemConfigurator subitem)
│   ├─► CPU: Option B  ← Different from Node 1!
│   └─► Warranty: Standard
│
└─► Network Switch (SimpleItem subitem)
    └─► Fixed Price: $800 × 2

The recursive getPrice() implementation naturally includes all these nested components, showing how the object-oriented approach simplifies complex configurations.

Architecture Overview

The refactoring moved from global state and monolithic functions to encapsulated objects with clear responsibilities:

Before: Global variables, 200+ line functions, simple price objects for subitems, no recursion support.

After: Encapsulated state in objects, modular methods, full configurator instances as subitems, recursive price calculation.

This enables multiple configurator instances to coexist, supports arbitrary nesting depth, and makes the code more testable and maintainable.

🎓 Why This Matters

This refactoring demonstrates:

  • How to evolve procedural code to OOP
  • Recursion applied to real-world problems
  • State management evolution patterns
  • Practical design pattern applications

About

2007 example: refactoring procedural JavaScript to OOP with recursive nested configuration

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages