- Implementation Patterns, Kent Beck, Addison-Wesley, 2007.
- Literate Programming, Donald E. Knuth, Center for the Study of Language and Information, Leland Stanford Junior University, 1992.
Principles mentioned:
Single Responsibility Principle (SRP), the Open Closed Principle (OCP), and the Dependency Inversion Principle (DIP)
* Chapter 2: Meaningful Names
** Use intention revealing names:
Names should reveal intent, there is no revelation in naming an integer ~d~, intending it stands for days. Instead, you should use the following names:
#+begin_src java
intelapsedTimeInDays;
intdaysSinceCreation;
intdaysSinceModification;
intfileAgeInDays;
#+end_src
** Avoid disinformation
Don't postfix the word 'list' to the name 'accounts' unless it's actually a list. This is because the reader will /assume/ the data type of accountsList is indeed a list, instead choose a name like ~accountsGroup~.
** Make Meaningful Distinctions
While it is possible to name by being disinformative, it is also possible to name being non informative. Consider:
#+begin_src java
publicstaticvoidcopyChars(chara1[],chara2[]){
for(inti=0;i<a1.length;i++){
a2[i]=a1[i];
}
}
#+end_src
What on earth does ~a[1]~ and ~a[2]~ even stand for? We are better off using names like source and destination (due to the function's intent of copying the array).
Furthermore, noise words are redundant. We should never use the word ~variable~ when naming a variable, or ~table~ when naming a table.
** Use Pronouncable Names
This is quite straightforward. Do not use a name like ~genymdhms~ to refer to generation date, year, month, day, hour, minute,
and second. Instead use ~generationTimeStamp~.
** Use Searchable Names
In modern IDE's, it is still quite difficult to search for single-lettered variables. The writer states a personal preference of using single-letter names only as local variables and inside short methods. The following principle is given:
/The length of a name should correspond to the size of its scope/
** Avoid Encodings
Don't prefix variables with letters like m_ as was done in the past. Do not type encode as well, an example of this is: ~PhoneNumber phoneString;~ we can see the reader being misled into thinking the phone number is a String.
** Avoid Mental Mappings
Clarity is king, don't use a name for a variable that only you know what it stands for. For example: using the letter r as the lower-cased version of the url with the host and scheme
removed. That's being smart, not professional.
** Class Names
{{{epigraph_single(Classes and objects should have noun or noun phrase names like Customer\, WikiPage\,
Account\, and AddressParser. Avoid words like Manager\, Processor\, Data\, or Info in the name
of a class. A class name should not be a verb)}}}
** Method Names
Methods should have verb or verb phrase names.
** Don't be cute/Don't use puns
Do not use names that are only understandable to people whom you share jokes etc with. Furthermore, do not use colloquialism and slang in names.
- Example: ~HandGrenade~ instead of ~DeleteItems~
- Example: ~whack()~ instead of ~kill()~
** Pick one word per concept
If you have multiple choices for naming a concept, use one and stick with it. For instance if your options are fetch, get and retrieve, use one and stick with it throughout.
** Solution Domain Names and Problem Domain Names
Where possible use solution domain names, as the people that are going to be reading the code are programmers. Therefore, do not shy away from using CS terms, algorithm names, math names and so forth.
However when it is not possible to use solution domain names (in other words, when there is no "programmer-eese" then use the name from the problem domain. The other programmers can ask the domain expert for clarification. If the code is more to do with the problem domain concepts, then the names should be drawn from them.
** Add Meaningful Context
Enclose names with well-named classes, functions, or namespaces. When all else fails, then prefix with something that provides more context.
** Don't add gratuitous context
Shorter names are better than longer ones, generally. This is so long as the context and intent is clear. Don't add redundant or irrelevant additions to the name in the for the sake of 'context'.
* Chapter 3: Functions
** Functions should be small
Functions should be extremely short—ideally just a few lines, so they remain easy to understand and maintain.
Avoid deeply nested blocks; keep indentation shallow (1–2 levels), often replacing blocks with descriptive function calls.
A small function tells a concise, self-contained story, making it easier for readers to follow the program’s intent.
The smaller the function, the more descriptive and accurate its name can be, improving self-documentation.
Large functions hide complexity and mix abstraction levels, making errors and duplication more likely.
** Do One Thing & One Level of Abstraction
A function should do exactly one conceptual task, and all its statements should exist at the same abstraction level.
Mixing details (like string concatenation) with high-level actions (like rendering a page) causes confusion.
The Stepdown Rule: organise functions so they read like a top down narrative, each calling the next abstraction level.
If you can extract a subfunction with a name that isn’t a restatement, the original function is doing too much.
Functions that “do one thing” cannot be logically split into sections such as “initialize,” “process,” “finalize.”
** Switch Statements
Switch statements naturally violate “do one thing” by handling multiple cases; they also grow in size over time.
They break the Single Responsibility Principle (multiple reasons to change) and Open-Closed Principle (must change for new cases).
Preferred approach: hide switch statements inside a factory and dispatch behavior polymorphically through an interface.
Allow only one visible switch in your system, used solely for object creation, then encapsulate it.
This removes duplication and keeps high-level code unaware of concrete type distinctions.
A function’s name should clearly state its purpose. Long, descriptive names beat short, cryptic ones.
Consistent naming patterns (shared verbs/nouns) help code read like a coherent story and aid predictability.
Descriptive names reduce the need for comments and improve comprehension without external documentation.
Renaming functions can reveal design improvements, so try multiple options until the best emerges.
IDE refactoring tools make renaming safe, encouraging experimentation.
** Function Arguments
{{{epigraph_single(The ideal number of arguments for a function is zero (niladic). Next comes one (monadic)\, followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.)}}}
Fewer arguments = better; aim for 0–2, avoid more than 3 unless absolutely necessary.
Flag arguments (booleans) are a red flag—they imply the function does multiple things.
Group related parameters into objects (e.g., ~Point~ for ~x~ and ~y~) to reduce argument count and improve clarity.
Output arguments are confusing—prefer returning values or mutating the owning object’s state.
Match function/argument names in verb–noun or keyword style (e.g., ~writeField(name)~, ~assertExpectedEqualsActual~).
** Have No Side Effects
A function should do only what its name promises. Hidden state changes are misleading and dangerous.
Side effects create temporal coupling, meaning the function must be called in a certain sequence to be safe.
If unavoidable, make side effects explicit in the name (e.g., ~checkPasswordAndInitializeSession~).
Clear separation of command and query functions avoids ambiguity in meaning and intent.
Functions that modify state and return information often cause confusion and should be split.
** Error Handling
Error handling is a single responsibility—separate it from normal logic to keep both paths clear.
Prefer exceptions over error codes to avoid cluttering the happy path and to reduce dependency magnets.
Extract try/catch bodies into their own functions for cleaner structure.
- Readers can skim like a newspaper: important first, details last.
- Contrast: C/C++ require declarations before use, Java does not.
*** Summary - vertical
- Use vertical openness to separate concepts.
- Use vertical density to group related ones.
- Keep related variables, methods, and concepts close together.
- Order code top down for natural readability.
** Horizontal Formatting
Keep lines short. Most professional code naturally stays within ~45 characters, with ~80 as an upper bound. Lines beyond 100–120 characters are generally careless.
Avoid shrinking font or overly wide monitors to fit more code, readability > fitting more characters.
Example limit guideline:
#+begin_src java
// Good (short)
intsum=a+b+c;
// Bad (too long)
intsum=a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q;
#+end_src
*** Horizontal Openness and Density
Use spaces to separate low-precedence operators (e.g., +, -, =) and improve readability.
Do not put spaces between function names and parentheses, they are closely related.
Example (Quadratic formula formatting):
#+begin_src java
return(-b+Math.sqrt(determinant))/(2*a);
#+end_src
Separate arguments with spaces after commas to show distinct parameters.
*** Horizontal Alignment
Avoid aligning variable declarations or assignments in columns, it draws the eye to the wrong place.
Long aligned lists usually mean the class is too large and should be split.
Example (preferred unaligned):
#+begin_src java
// Prefer this:
privateSocketsocket;
privateInputStreaminput;
privateOutputStreamoutput;
//instead of:
privateSocketsocket;
privateInputStreaminput;
privateOutputStreamoutput;
#+end_src
*** Indentation
Indent according to scope hierarchy:
Classes → no indent
Methods → 1 level
Method bodies → 2 levels
Inner blocks → +1 for each nesting
Indentation makes scopes visually obvious; without it, code is hard to scan.
Avoid collapsing scopes onto one line, always use braces and proper indenting.
*** Dummy Scopes
Avoid dummy bodies in loops (e.g., empty while or for loops).
If unavoidable, place semicolon on its own indented line to make it visible.
#+begin_src java
while(dis.read(buf,0,size)!=-1)
;
#+end_src
** Team Rules
Teams must agree on a single formatting style for consistency.
Use IDE formatters to enforce these rules across all files.
Consistent formatting builds trust and reduces mental load for readers.
** Uncle Bob’s Formatting Rules (Example in CodeAnalyzer.java)
Short, clear methods with consistent spacing and indentation.
Use spaces around assignment and low-precedence operators, no space for high precedence operators.
@@ -518,3 +518,9 @@ at <ScriptBlock>, /home/zaine/master-folder/org-platform/org_web/gitea-build-mon
2026-07-08T01:02:07.5213424+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python.
2026-07-08T01:02:08.0097024+01:00 [INFO] Sent authoring server test notification.
2026-07-08T21:39:46.0576365+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success
2026-07-08T21:39:46.0662048+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web.
2026-07-08T21:39:47.2301237+01:00 [INFO] Sent build status notification with 1 embed(s).
2026-07-08T21:39:47.2502852+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.