Before adding abstraction, asks "do we need this now?" Activates when proposing factories, abstract classes, config-driven behavior, or "for future extensibility." Resists over-engineering. Three similar lines are better than a premature abstraction.
Before adding abstraction, answer honestly:
## Complexity Check
**I want to add:** [describe the abstraction]
**Because:** [your justification]
**Is this solving a problem we have TODAY?**
- [ ] Yes, we have 3+ concrete cases now
- [ ] No, but we might need it later
**If "might need later":** Don't build it. Stop.
Abstract when you have three concrete cases, not before:
| Situation | Action | |-----------|--------| | 1 case | Just write it | | 2 cases | Copy-paste is fine. Note the duplication. | | 3 cases | Now consider abstracting |
// With 1 button: just make the button
<button class="blue">Save</button>
// With 2 buttons: copy-paste is fine
<button class="blue">Save</button>
<button class="red">Delete</button>
// With 3+ buttons: NOW consider a component
<Button color="blue">Save</Button>
<Button color="red">Delete</Button>
<Button color="gray">Cancel</Button>
Watch for these phrases in your thinking:
Watch for these patterns:
| Instead of | Try | |------------|-----| | Factory pattern | Direct instantiation | | Abstract base class | Concrete class | | Config-driven behavior | Hardcoded behavior | | Dependency injection | Direct imports | | Custom event system | Callbacks | | Generic utility | Inline code |
Abstraction is warranted when:
When resisting complexity:
## Keeping It Simple
**Considered:** [the abstraction]
**Rejected because:** [only N cases / speculative / etc.]
**Instead:** [simpler approach]
When complexity is warranted:
## Abstraction Justified
**Adding:** [the abstraction]
**Because:** [3+ cases / causing bugs / stable pattern]
**Cases:** [list the concrete cases]
User: "Add a way to send notification emails"
Over-engineered approach:
NotificationFactory
├── EmailNotification
├── SMSNotification (might need later!)
├── PushNotification (could be useful!)
└── NotificationConfig
├── templates
├── retryPolicy
└── queueSettings
YAGNI approach:
def send_notification_email(user, subject, body):
email_service.send(
to=user.email,
subject=subject,
body=body
)
Why simpler is better:
The 5-line function solves the actual problem. The factory solves imaginary ones.
<failed-attempts> What DOESN'T work:Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer