一键导入
reducing-complexity
Managing complexity is software's primary technical imperative - all other goals are secondary
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Managing complexity is software's primary technical imperative - all other goals are secondary
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Fork, clone to ~/.clank, run installer, edit CLAUDE.md
RED-GREEN-REFACTOR for process documentation - baseline without skill, write addressing failures, iterate closing loopholes
Skills wiki intro - mandatory workflows, search tool, brainstorming triggers
Interactive idea refinement using Socratic method to develop fully-formed designs
Execute detailed plans in batches with review checkpoints
Execute implementation plan by dispatching fresh subagent for each task, with code review between tasks
| name | Reducing Complexity |
| description | Managing complexity is software's primary technical imperative - all other goals are secondary |
| when_to_use | Before and during any design or implementation. When solution feels complicated. When code is hard to understand. When you can't keep entire design in mind. When complexity is proliferating. When applying methods mechanically without understanding why. |
| version | 1.0.0 |
| languages | all |
Managing complexity is the most important technical topic in software development. All other technical goals—performance, features, elegance—are secondary to managing complexity.
Core principle: "There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies, and the other is to make it so complicated that there are no obvious deficiencies." - C.A.R. Hoare
Always choose the first way.
Use as guiding principle for EVERY technical decision:
Warning signs of complexity overload:
Inherent in the real-world problem itself. Can't be eliminated, only managed.
Examples:
Approach: Minimize what anyone's brain must deal with at one time.
Complexity we introduce through our design and implementation choices. CAN be eliminated.
Examples:
Approach: Keep accidental complexity from needlessly proliferating.
Two fundamental approaches, three practical strategies:
Implemented through three strategies:
Dijkstra's insight: No one's skull is big enough to contain a modern program. Organize programs so you can safely focus on one part at a time.
Think of it as mental juggling: More mental balls to keep in air = more likely to drop one = design or coding error.
At each level:
Goal: Make each piece simple enough to understand fully in isolation.
Good design lets you safely IGNORE most of the program while working on any one part.
Questions to ask:
If answer is no: Design isn't doing its job. Increase encapsulation, reduce coupling.
Each abstraction should:
Example:
# ❌ Low-level, complex
current_font.attribute = current_font.attribute or 0x02
# ✅ High-level, simple
current_font.set_bold_on()
Working with fonts (problem domain) > manipulating bit fields (implementation domain)
All aimed at managing complexity:
| Characteristic | Why It Reduces Complexity |
|---|---|
| Minimal complexity | Primary goal - avoid clever designs, prefer simple |
| Loose coupling | Minimize connections between parts |
| High fan-in | Reuse utility classes (don't duplicate) |
| Low fan-out | Each class uses few other classes (< 7) |
| Leanness | No extra parts - finished when nothing more can be removed |
| Stratification | Consistent abstraction levels - don't mix high and low |
| Good abstraction | Interface hides implementation details |
| Good encapsulation | Implementation details truly hidden |
Each characteristic makes it easier to focus on one thing at a time.
Ask yourself:
If you hesitate on any question, simplify further.
Complexity overload symptom: "Doggedly applying a method that is clearly irrelevant." Like a mechanic whose car breaks down, so he puts water in the battery and empties the ashtrays.
If you catch yourself doing things mechanically without understanding why → STOP.
Good design feels elegant and obvious:
Quote: "When I am working on a problem I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." - R. Buckminster Fuller
Partition into subsystems with clear boundaries:
Think of it as hoses with water: More hoses to disconnect when pulling out a subsystem = more complexity. Minimize connections.
Each class implements ONE abstract data type:
❌ Bad: Class with methods for command stack, report formatting, AND global data initialization ✅ Good: Separate classes, each with focused purpose
Keep routines short and focused:
Length guideline: Natural length determined by function, but if > 200 lines, strongly consider splitting.
Write in terms of problem domain, not implementation:
| When | Technique |
|---|---|
| Routine too complex | Extract parts into smaller routines |
| Class too complex | Split into multiple focused classes |
| Parameter list too long | Group related parameters into object |
| Deep nesting | Extract nested logic into routines, use early returns |
| Duplicate code | Extract into shared routine |
| Complex conditional | Extract into well-named boolean function |
| Magic numbers | Replace with named constants |
| Low-level operations | Hide behind high-level abstraction |
Watch for and eliminate:
Over-engineering
Clever code
Inconsistency
Poor organization
Lack of encapsulation
More flexibility usually = more complexity
Examples of flexibility vs complexity:
Rule: Build in flexibility needed to meet requirements. Don't add flexibility beyond what's required.
Ask: Do we ACTUALLY need this flexibility, or are we speculating about future needs?
All of these mean: Iterate on design to find simpler approach.
Informal metrics:
Formal metrics (if you need them):
Most important: If it FEELS complex, it probably IS complex.
Complexity reduction supports:
Everything gets easier when you reduce complexity first.
Generally, simplicity wins. But some scenarios genuinely require complexity:
When complexity is acceptable:
Example: High-frequency trading system needs complex cache with eviction policies because every microsecond matters AND this has been measured.
Rule: Measure first, optimize second. Start simple, add complexity only when evidence demands it.
When complexity is justified:
Example: Aviation software with multiple redundant systems and extensive validation.
Rule: Safety complexity must be systematic and well-documented, not ad-hoc.
When complexity can't be avoided immediately:
Strategy: Contain the complexity (see Legacy Code Strategy below).
Before accepting complexity as necessary:
If you can't answer YES to all five: The complexity probably isn't justified.
You inherit complex codebase. What do you do?
Rule Zero: Every change either reduces complexity or holds it steady. Never add to the complexity.
When touching legacy code:
"Boy scout rule": Always leave code cleaner than you found it.
Build barriers around complex legacy code:
Example from Code Complete:
# Old system has terrible naming and structure
# Don't let it spread - create clean interface layer
class LegacyUserSystem: # Hidden behind interface
def get_usr_dat_rec(self, id): ... # Terrible legacy code
class UserRepository: # Clean interface your code uses
def get_user(self, user_id):
# Adapter: translates to/from legacy
legacy = LegacyUserSystem()
user_data = legacy.get_usr_dat_rec(user_id)
return User.from_legacy(user_data) # Convert to clean model
Now new code only sees UserRepository.get_user() - simple and clear.
Can't simplify everything at once. What first?
Measure: Track which files are modified most frequently. Simplify those first.
Don't rewrite entire system. Incrementally reduce complexity:
Each refactoring makes one piece simpler. Do many, and complexity drops significantly.
Every other technical goal is secondary to managing complexity:
When in doubt, choose simpler.
From Code Complete:
Quote: "When software-project surveys report causes of project failure, they rarely identify technical reasons as primary causes... But when projects do fail for reasons that are primarily technical, the reason is often uncontrolled complexity."
Two ways to reduce complexity:
Both require conscious, continuous effort.
Managing complexity isn't optional. It's THE fundamental technical imperative.