← All material

Core JavaScript · 8 of 9

Case Study: Refactoring a Namespace Class

Putting it together: here's a small order-total service in the old style, then the same behavior rebuilt as an ES module using the patterns from this path.

Before

namespace Orders {
  export class OrderService {
    private items: { price: number; qty: number }[] = [];

    add(price: number, qty: number): void {
      this.items.push({ price, qty });
    }

    total(): number {
      let sum = 0;
      for (const item of this.items) {
        sum += item.price * item.qty;
      }
      return sum;
    }
  }
}

const service = new Orders.OrderService();
service.add(10, 2);
service.total(); // 20

After

// order-service.js
const itemTotal = (item) => {
  return item.price * item.qty;
};

export const createOrder = () => {
  let items = [];

  return {
    add(price, qty) {
      items = [...items, { price, qty }];
    },
    total() {
      return items.reduce((sum, item) => sum + itemTotal(item), 0);
    },
  };
};

// usage
import { createOrder } from "./order-service.js";

const order = createOrder();
order.add(10, 2);
order.total(); // 20

What changed

Nothing here is a rule to apply everywhere — but it's the default worth reaching for first, before a class.