| name | dry-options-pattern |
| description | **Description:** Use when consolidating multiple similar formatting functions into one. Applies to any case where 2-3 functions share 80%+ logic but differ in output format or filtering. |
DRY Options Pattern for Formatter Functions
Description: Use when consolidating multiple similar formatting functions into one. Applies to any case where 2-3 functions share 80%+ logic but differ in output format or filtering.
The Pattern
When you find multiple functions that:
- Read from the same data source
- Iterate the same way
- Differ only in formatting, filtering, or header/footer text
Consolidate into one function with an options object:
export interface CommandHelpOptions {
format?: 'verbose' | 'compact';
role?: string;
}
export function buildCommandHelp(options?: CommandHelpOptions): string {
const format = options?.format ?? 'verbose';
}
Applied Example: CommandHelp.ts
Before (3 functions):
buildCommandHelp() — verbose, no role filter
buildCommandReminder(role?) — compact, with role filter
buildCommandReminderMessage(role?) — trivial wrapper
After (1 function):
buildCommandHelp(options?) — format controls verbose/compact, role controls filtering
- Callers:
buildCommandHelp() for errors, buildCommandHelp({ format: 'compact', role }) for reminders
Checklist
- Identify shared data source and iteration logic
- List the differences between functions (format, filtering, headers/footers)
- Design options interface with sensible defaults (most common use = no args)
- Move filtering logic inside the function gated by options
- Update all callers — trivial wrappers become direct calls
- Remove the duplicates entirely
- Update tests to cover both format paths