Course progress0%
Course content
45 min

Boundaries before More Files

Organize modules by responsibility and direction of dependency

By the end of this lesson

  • Organize modules by responsibility and direction of dependency
  • Keep pricing policy independent of browser and server transport

The file has become difficult to change

Your main module loads data, parses fields, calculates prices, changes status and rewrites the screen. Splitting every ten lines into another file will not automatically make those responsibilities clear.

Begin with a change request: "Display amounts differently, while preserving every price calculation." You should be able to locate the formatter without inspecting HTTP or storage code. Then ask: "Change the premium threshold." That should lead to the domain policy and its tests.

Choose dependency directions

domain/        pricing, validation, allowed transitions
application/   actions, state, orchestration
adapters/      HTTP and local storage
ui/            read form values, render state, bind events
main.js        construct and connect the pieces

These are suggested responsibilities, not a requirement to create empty directories. Domain functions do not import the DOM, fetch or storage. UI functions call application actions rather than inventing business rules. The application receives adapters so tests can replace them. main.js is the composition point where the concrete browser dependencies meet.

Server code can import the pure pricing module but must own its authoritative input mapping and request checks. Shared code is not shared trust: the server still decides which data to pass to it.

Refactor one boundary at a time

  1. Preserve your passing behavior checks.
  2. Extract one pure calculation or transition with explicit parameters and return values.
  3. Move HTTP access behind the adapter you already tested.
  4. Make rendering accept state rather than reading totals back from the screen.
  5. Wire the dependencies once at startup and run the checks again.

Update the local server's explicit static map whenever browser file URLs move. A 404 after a refactor is an integration defect, even if unit tests still pass.

Detect a dependency problem

If pricing.js imports render.js to show an error, the direction is wrong. Return a result or throw a domain error; let the caller decide how to present it. If the storage module imports the page to find a customer name, pass it a validated draft instead.

A little duplication in unrelated presentation code may be clearer than a universal helper with twelve options. Extract an abstraction when you can name the shared responsibility and describe its contract.

Evidence and handoff

Draw your actual import relationships and identify any cycle. Give each module a one-sentence responsibility. A teammate should be able to change an error message, a tax rule and an API path by starting in three predictable places.

Submit one refactor diff with unchanged acceptance results. Your decision journal should explain why the boundary helps the next likely change, not simply that the code looks cleaner.

Lesson complete?

Your progress is saved on this device.