Skip to content

Commit 4edfaca

Browse files
authored
Merge pull request #444 from raifdmueller/add-slap-occam-code-smells-anchors
feat: add SLAP, Occam's Razor, Code Smells anchors (#440, #439, #435)
2 parents 234ba58 + ff68d81 commit 4edfaca

12 files changed

Lines changed: 462 additions & 6 deletions

docs/anchors/code-smells.adoc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
= Code Smells
2+
:categories: design-principles
3+
:roles: software-developer, software-architect, educator, team-lead
4+
:related: fowler-patterns, cohesion-criteria, solid-principles, solid-srp, kiss-principle
5+
:proponents: Kent Beck, Martin Fowler, Robert C. Martin
6+
:tags: refactoring, code-quality, clean-code, maintainability, smells
7+
:tier: 2
8+
9+
[%collapsible]
10+
====
11+
Full Name:: Code Smells
12+
13+
Also known as:: Bad Smells in Code, Refactoring Smells
14+
15+
[discrete]
16+
== *Core Concepts*:
17+
18+
What a smell is::
19+
A *surface indication* in the code that usually points to a deeper design problem. Smells are heuristic: they are quick to spot, do not prove a defect exists, and are evaluated in context. A smell tells you *where to look*, not *what to do*.
20+
21+
Fowler's catalogue::
22+
Martin Fowler's _Refactoring_ (1999, 2nd ed. 2018, with the original smell chapter co-authored by Kent Beck) is the canonical catalogue. Each smell is paired with a refactoring that typically resolves it. Common groupings of Fowler's 20+ smells:
23+
+
24+
* *Bloaters* — structures that grow too large: Long Method, Large Class, Long Parameter List, Primitive Obsession, Data Clumps.
25+
* *Object-Orientation Abusers* — incomplete or inverted use of OO: Switch Statements, Refused Bequest, Alternative Classes with Different Interfaces, Temporary Field.
26+
* *Change Preventers* — structures that multiply the cost of change: Divergent Change (one class changes for many reasons), Shotgun Surgery (one change touches many classes), Parallel Inheritance Hierarchies.
27+
* *Dispensables* — code that earns its keep poorly: Comments (as compensation), Duplicate Code, Lazy Class, Data Class, Dead Code, Speculative Generality.
28+
* *Couplers* — excessive or inappropriate coupling: Feature Envy, Inappropriate Intimacy, Message Chains, Middle Man.
29+
30+
Martin's extensions::
31+
Robert C. Martin's _Clean Code_ (2008), Appendix A "Smells and Heuristics", extends Fowler's catalogue with additional smells organised by concern — Comments, Environment, Functions, General, Java, Names, Tests — about 65 heuristics in total. These are complementary refinements, not a replacement for Fowler's set.
32+
33+
Terminology origin::
34+
Kent Beck coined the term "code smell" in the 1990s; Fowler wrote the book that made it the standard vocabulary. "It just feels wrong" became expressible and teachable.
35+
36+
Key Proponents:: Kent Beck (coined the term), Martin Fowler (_Refactoring_, 1999, 2nd ed. 2018 — canonical catalogue), Robert C. Martin (_Clean Code_, 2008, Appendix A — extended enumeration).
37+
38+
[discrete]
39+
== *When to Use*:
40+
41+
* Code review: a shared vocabulary for "this feels wrong" that turns taste into checkable signals
42+
* Refactoring planning: each smell maps to known refactorings, so a smell is an actionable handle
43+
* Teaching: junior developers learn faster from a named smell + named fix than from abstract design lectures
44+
* Technical-debt inventory: enumerate smells to quantify and prioritise cleanup work
45+
* LLM prompting: asking the model to "identify code smells" activates a richer inspection than "find problems"
46+
* Self-review before PR: a mental pass over the smell list catches issues a reader would otherwise flag
47+
48+
[discrete]
49+
== *Related Anchors*:
50+
51+
* <<fowler-patterns,Patterns of Enterprise Application Architecture>> - Same author; Fowler's broader design-pattern vocabulary
52+
* <<cohesion-criteria,Cohesion Criteria>> - Many smells (Feature Envy, Divergent Change, Large Class) are low-cohesion symptoms
53+
* <<solid-principles,SOLID Principles>> - SOLID violations manifest as identifiable smells; smell→principle is a useful diagnostic direction
54+
* <<solid-srp,SOLID SRP>> - Divergent Change is almost always an SRP violation
55+
* <<kiss-principle,KISS Principle>> - Speculative Generality and Comments-as-compensation are KISS failures
56+
====

docs/anchors/code-smells.de.adoc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
= Code Smells
2+
:categories: design-principles
3+
:roles: software-developer, software-architect, educator, team-lead
4+
:related: fowler-patterns, cohesion-criteria, solid-principles, solid-srp, kiss-principle
5+
:proponents: Kent Beck, Martin Fowler, Robert C. Martin
6+
:tags: refactoring, code-qualität, clean-code, wartbarkeit, smells
7+
:tier: 2
8+
9+
[%collapsible]
10+
====
11+
Vollständiger Name:: Code Smells
12+
13+
Auch bekannt als:: Bad Smells in Code, Refactoring-Smells, "schlechter Geruch im Code"
14+
15+
[discrete]
16+
== *Kernkonzepte*:
17+
18+
Was ein Smell ist::
19+
Ein *oberflächliches Indiz* im Code, das üblicherweise auf ein tieferliegendes Designproblem hinweist. Smells sind heuristisch: sie sind schnell zu erkennen, beweisen keinen Defekt und müssen im Kontext bewertet werden. Ein Smell sagt dir *wo du hinschauen sollst*, nicht *was zu tun ist*.
20+
21+
Fowlers Katalog::
22+
Martin Fowlers _Refactoring_ (1999, 2. Aufl. 2018, das ursprüngliche Smell-Kapitel zusammen mit Kent Beck) ist der kanonische Katalog. Jeder Smell ist mit einem Refactoring gepaart, das ihn typischerweise auflöst. Übliche Gruppierung der über 20 Fowler-Smells:
23+
+
24+
* *Bloaters* — zu groß gewachsene Strukturen: Long Method, Large Class, Long Parameter List, Primitive Obsession, Data Clumps.
25+
* *Object-Orientation Abusers* — unvollständige oder verdrehte OO-Nutzung: Switch Statements, Refused Bequest, Alternative Classes with Different Interfaces, Temporary Field.
26+
* *Change Preventers* — Strukturen, die Änderungskosten vervielfachen: Divergent Change (eine Klasse ändert sich aus vielen Gründen), Shotgun Surgery (eine Änderung berührt viele Klassen), Parallel Inheritance Hierarchies.
27+
* *Dispensables* — Code, der seinen Platz schlecht rechtfertigt: Comments (als Kompensation), Duplicate Code, Lazy Class, Data Class, Dead Code, Speculative Generality.
28+
* *Couplers* — übermäßige oder unangemessene Kopplung: Feature Envy, Inappropriate Intimacy, Message Chains, Middle Man.
29+
30+
Martins Erweiterungen::
31+
Robert C. Martins _Clean Code_ (2008), Anhang A "Smells and Heuristics", erweitert Fowlers Katalog um weitere Smells, organisiert nach Thema — Comments, Environment, Functions, General, Java, Names, Tests — insgesamt ca. 65 Heuristiken. Das sind komplementäre Verfeinerungen, kein Ersatz für Fowlers Set.
32+
33+
Herkunft des Begriffs::
34+
Kent Beck prägte den Begriff "Code Smell" in den 1990ern; Fowler schrieb das Buch, das ihn zum Standardvokabular machte. "Fühlt sich irgendwie falsch an" wurde damit ausdrückbar und lehrbar.
35+
36+
Schlüsselvertreter:: Kent Beck (Begriffsprägung), Martin Fowler (_Refactoring_, 1999, 2. Aufl. 2018 — kanonischer Katalog), Robert C. Martin (_Clean Code_, 2008, Anhang A — erweiterte Enumeration).
37+
38+
[discrete]
39+
== *Wann zu verwenden*:
40+
41+
* Code Review: gemeinsames Vokabular für "das fühlt sich falsch an", das Geschmack in prüfbare Signale verwandelt
42+
* Refactoring-Planung: jeder Smell ist mit bekannten Refactorings verknüpft, also ein handlungsleitender Griff
43+
* Lehre: Junior-Entwickler lernen schneller an benanntem Smell + benanntem Fix als an abstrakten Designvorträgen
44+
* Technical-Debt-Inventur: Smells zählen, um Aufräumarbeit zu quantifizieren und zu priorisieren
45+
* LLM-Prompting: "identifiziere Code Smells" aktiviert eine reichere Inspektion als "finde Probleme"
46+
* Selbst-Review vor PR: ein mentaler Durchgang über die Smell-Liste fängt Issues, die ein Reviewer sonst flagt
47+
48+
[discrete]
49+
== *Verwandte Anker*:
50+
51+
* <<fowler-patterns,Patterns of Enterprise Application Architecture>> - Gleicher Autor; Fowlers breiteres Design-Pattern-Vokabular
52+
* <<cohesion-criteria,Kohäsionskriterien>> - Viele Smells (Feature Envy, Divergent Change, Large Class) sind Symptome niedriger Kohäsion
53+
* <<solid-principles,SOLID-Prinzipien>> - SOLID-Verletzungen zeigen sich als erkennbare Smells; Smell→Prinzip ist eine nützliche Diagnoserichtung
54+
* <<solid-srp,SOLID SRP>> - Divergent Change ist fast immer eine SRP-Verletzung
55+
* <<kiss-principle,KISS-Prinzip>> - Speculative Generality und Comments-als-Kompensation sind KISS-Verstöße
56+
====

docs/anchors/occams-razor.adoc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
= Occam's Razor
2+
:categories: problem-solving
3+
:roles: software-architect, software-developer, consultant, educator
4+
:related: kiss-principle, yagni, five-whys, mece, devils-advocate
5+
:proponents: William of Ockham
6+
:tags: heuristic, parsimony, epistemology, simplicity, hypothesis-selection
7+
:tier: 2
8+
9+
[%collapsible]
10+
====
11+
Full Name:: Occam's Razor (also spelled Ockham's Razor)
12+
13+
Also known as:: Law of Parsimony, Principle of Parsimony, _Lex Parsimoniae_, "Entities should not be multiplied beyond necessity"
14+
15+
[discrete]
16+
== *Core Concepts*:
17+
18+
Core rule::
19+
Among competing hypotheses that explain the same observations equally well, prefer the one that requires the fewest assumptions. The razor *shaves off* unnecessary entities, causes, or mechanisms.
20+
21+
What it is *not*::
22+
* Not a rule to be brief or terse — that is a stylistic choice, not an epistemic one.
23+
* Not a proof that the simpler answer is *true* — only a guide to which hypothesis to prefer, investigate first, or commit to under uncertainty.
24+
* Not a licence for KISS-style solution simplification — Occam operates at the level of *explanations*, KISS at the level of *solutions*. They overlap but are not the same razor.
25+
26+
How it is used::
27+
* As a *selection filter* under uncertainty — when two stories fit the data, start with the one that assumes less.
28+
* As a *debugging heuristic* — before assuming a bug requires a race condition plus caching layer plus stale DNS, check whether a single off-by-one explains everything.
29+
* In *architecture decisions* — a design that needs three new components to justify itself is evidentially weaker than one that reuses existing pieces.
30+
* In *diagnostic reasoning* — prefer explanations grounded in the system's known mechanics over ones that require novel failure modes.
31+
32+
Limits and counters::
33+
The razor is a *prior*, not a verdict. Reality is frequently non-parsimonious, and "simpler" is relative to a chosen ontology. Einstein's corollary — "_as simple as possible, but no simpler_" — warns against under-fitting. Pair Occam with evidence, not as a substitute for it.
34+
35+
Key Proponents:: William of Ockham (c. 1287–1347, _Summa Logicae_, _Quodlibetal Questions_); the principle predates Ockham in Aristotle and Scotus but carries his name due to his repeated methodological use of it. Modernised by Bertrand Russell and formalised as minimum-description-length / Bayesian simplicity priors in 20th-century philosophy of science.
36+
37+
[discrete]
38+
== *When to Use*:
39+
40+
* Debugging: triage competing theories of a bug before instrumenting for all of them
41+
* Architecture review: challenge proposals that introduce new components to explain observed requirements
42+
* Root-cause analysis: pair with Five Whys to avoid stopping at an elaborate but unjustified explanation
43+
* Incident response: the outage likely has *one* cause matching the data, not a conspiracy
44+
* Requirements clarification: pick the interpretation that requires fewest hidden assumptions about the user
45+
* LLM prompting: ask the model to prefer the explanation with the fewest moving parts when diagnosing
46+
47+
[discrete]
48+
== *Related Anchors*:
49+
50+
* <<kiss-principle,KISS Principle>> - Sibling razor applied to *solutions* rather than *explanations*
51+
* <<yagni,YAGNI>> - Applies parsimony to future requirements: don't build what you can't justify
52+
* <<five-whys,Five Whys>> - Occam helps pick which "why" to pursue when the chain forks
53+
* <<mece,MECE Principle>> - Both disciplines of hypothesis hygiene; MECE ensures coverage, Occam ranks by parsimony
54+
* <<devils-advocate,Devil's Advocate>> - Devil's Advocate stress-tests the hypothesis Occam has selected
55+
====

docs/anchors/occams-razor.de.adoc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
= Occams Rasiermesser
2+
:categories: problem-solving
3+
:roles: software-architect, software-developer, consultant, educator
4+
:related: kiss-principle, yagni, five-whys, mece, devils-advocate
5+
:proponents: William of Ockham
6+
:tags: heuristik, sparsamkeit, epistemologie, einfachheit, hypothesenauswahl
7+
:tier: 2
8+
9+
[%collapsible]
10+
====
11+
Vollständiger Name:: Occams Rasiermesser (auch Ockhams Rasiermesser)
12+
13+
Auch bekannt als:: Sparsamkeitsprinzip, Prinzip der Parsimonie, _Lex Parsimoniae_, "Entitäten sind nicht über das Notwendige hinaus zu vermehren"
14+
15+
[discrete]
16+
== *Kernkonzepte*:
17+
18+
Grundregel::
19+
Unter konkurrierenden Hypothesen, die dieselben Beobachtungen gleich gut erklären, bevorzuge diejenige mit den wenigsten Annahmen. Das Rasiermesser *schneidet* unnötige Entitäten, Ursachen oder Mechanismen weg.
20+
21+
Was es *nicht* ist::
22+
* Keine Regel, sich kurzzufassen — das wäre stilistisch, nicht erkenntnistheoretisch.
23+
* Kein Beweis, dass die einfachere Antwort *wahr* ist — nur eine Präferenzregel, welche Hypothese zuerst zu untersuchen oder unter Unsicherheit anzunehmen ist.
24+
* Keine Lizenz für KISS-artige Lösungsvereinfachung — Occam arbeitet auf der Ebene der *Erklärungen*, KISS auf der Ebene der *Lösungen*. Sie überlappen, sind aber nicht dasselbe Rasiermesser.
25+
26+
Wie es angewendet wird::
27+
* Als *Auswahlfilter* unter Unsicherheit — wenn zwei Geschichten zu den Daten passen, beginne mit der, die weniger annimmt.
28+
* Als *Debugging-Heuristik* — bevor du annimmst, dass ein Bug eine Race Condition plus Caching-Schicht plus veralteten DNS braucht, prüfe, ob ein einzelner Off-by-One alles erklärt.
29+
* Bei *Architekturentscheidungen* — ein Entwurf, der drei neue Komponenten zu seiner Rechtfertigung braucht, steht evidenziell schwächer da als einer, der Bestehendes wiederverwendet.
30+
* Im *diagnostischen Denken* — bevorzuge Erklärungen, die auf den bekannten Mechanismen des Systems basieren, gegenüber solchen, die neue Fehlermodi voraussetzen.
31+
32+
Grenzen und Gegenargumente::
33+
Das Rasiermesser ist ein *Prior*, kein Urteil. Die Realität ist häufig nicht sparsam, und "einfacher" ist relativ zur gewählten Ontologie. Einsteins Korollar — "_so einfach wie möglich, aber nicht einfacher_" — warnt vor Underfitting. Paare Occam mit Evidenz, nicht als Ersatz für sie.
34+
35+
Schlüsselvertreter:: Wilhelm von Ockham (ca. 1287–1347, _Summa Logicae_, _Quodlibeta_); das Prinzip ist älter (Aristoteles, Duns Scotus), trägt aber Ockhams Namen wegen seines konsequenten methodischen Einsatzes. Modernisiert durch Bertrand Russell und in der Wissenschaftsphilosophie des 20. Jh. als Minimum-Description-Length / Bayesianische Simplicity-Priors formalisiert.
36+
37+
[discrete]
38+
== *Wann zu verwenden*:
39+
40+
* Debugging: konkurrierende Theorien für einen Bug triagieren, bevor du für alle instrumentierst
41+
* Architektur-Review: Vorschläge hinterfragen, die neue Komponenten einführen, um beobachtete Anforderungen zu erklären
42+
* Root-Cause-Analyse: kombiniert mit Five Whys verhindert Stehenbleiben bei elaborierten, aber unbegründeten Erklärungen
43+
* Incident Response: der Ausfall hat wahrscheinlich *eine* Ursache, die zu den Daten passt, keine Verschwörung
44+
* Requirements-Klärung: wähle die Interpretation, die die wenigsten versteckten Annahmen über den Nutzer macht
45+
* LLM-Prompting: bitte das Modell, bei der Diagnose die Erklärung mit den wenigsten beweglichen Teilen zu bevorzugen
46+
47+
[discrete]
48+
== *Verwandte Anker*:
49+
50+
* <<kiss-principle,KISS-Prinzip>> - Verwandtes Rasiermesser, angewandt auf *Lösungen* statt *Erklärungen*
51+
* <<yagni,YAGNI>> - Überträgt Parsimonie auf zukünftige Anforderungen: baue nicht, was du nicht rechtfertigen kannst
52+
* <<five-whys,Five Whys>> - Occam hilft zu wählen, welchem "Warum" zu folgen ist, wenn die Kette sich verzweigt
53+
* <<mece,MECE-Prinzip>> - Beide sind Hygienewerkzeuge für Hypothesen; MECE sichert Abdeckung, Occam bewertet nach Sparsamkeit
54+
* <<devils-advocate,Devil's Advocate>> - Devil's Advocate stresst die von Occam gewählte Hypothese
55+
====
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
= Single Level of Abstraction Principle (SLAP)
2+
:categories: design-principles
3+
:roles: software-developer, software-architect, educator
4+
:related: cohesion-criteria, kiss-principle, solid-srp, clean-architecture
5+
:proponents: Kent Beck, Robert C. Martin
6+
:tags: clean-code, abstraction, function-design, readability, composed-method
7+
:tier: 2
8+
9+
[%collapsible]
10+
====
11+
Full Name:: Single Level of Abstraction Principle
12+
13+
Also known as:: SLAP, SLA Principle, One Level of Abstraction Per Function
14+
15+
[discrete]
16+
== *Core Concepts*:
17+
18+
Core rule::
19+
All statements within a single function (or block) should operate at the same level of abstraction. High-level orchestration and low-level mechanics do not belong in the same body.
20+
21+
Why it works::
22+
A reader scanning a function can trust it to answer *one* question at *one* resolution. Mixing levels forces the reader to context-switch between "what is this step doing" and "how exactly is it being done" on every line, which is the primary driver of the "I have to read this three times" feeling.
23+
24+
Applying SLAP::
25+
* When you notice a function mixing levels, extract the low-level details into well-named helper functions whose names *express the next level of detail*.
26+
* The top-level function becomes a readable summary — almost a table of contents — of the work.
27+
* This is the *Composed Method* pattern (Kent Beck, _Smalltalk Best Practice Patterns_, 1996): build functions from calls to other methods at the same conceptual level.
28+
29+
Relation to Clean Code::
30+
Robert C. Martin formalised SLAP as one of the function-design rules in _Clean Code_ (2008), alongside "Functions should be small", "Do one thing", and "Use descriptive names". SLAP is the organising principle that makes "small functions" readable rather than just fragmented.
31+
32+
Key Proponents:: Kent Beck (_Smalltalk Best Practice Patterns_, 1996 — "Composed Method"), Robert C. Martin (_Clean Code_, 2008).
33+
34+
[discrete]
35+
== *When to Use*:
36+
37+
* Refactoring a long function that "does too much" — SLAP tells you *how* to split it, not just that you should
38+
* Code review: a natural smell-detector for functions that mix orchestration with mechanics
39+
* Teaching junior developers a concrete, checkable rule that produces readable code
40+
* Designing a new algorithm top-down: write the high-level steps as calls to not-yet-existing helpers, then fill them in
41+
* Reconstructing the intent of legacy code — lift the orchestration out and the design becomes visible
42+
43+
[discrete]
44+
== *Related Anchors*:
45+
46+
* <<cohesion-criteria,Cohesion Criteria>> - SLAP produces functional cohesion by keeping a function focused on one conceptual step
47+
* <<kiss-principle,KISS Principle>> - SLAP is one concrete technique for keeping functions simple
48+
* <<solid-srp,SOLID SRP>> - SRP applies at the class level what SLAP applies at the function level
49+
* <<clean-architecture,Clean Architecture>> - Layered abstraction at the architectural scale mirrors SLAP at the code scale
50+
====

0 commit comments

Comments
 (0)