Fundamentals 25 min read

Master Essential Programming Principles: KISS, YAGNI, SOLID and More

This article compiles core programming principles such as KISS, YAGNI, Separation of Concerns, DRY, Inversion of Control and the SOLID rules, explaining why each matters, how to apply them, and providing reference links for deeper study.

Programmer DD
Programmer DD
Programmer DD
Master Essential Programming Principles: KISS, YAGNI, SOLID and More

Every programmer can benefit from understanding programming principles and patterns. This overview, originally translated from the "Programming Principles" site, lists key guidelines and offers brief explanations, reasons, practical steps, and further reading.

KISS

Most systems work best when they stay simple rather than complex.

Why

Less code means less time to write, fewer bugs, and easier modifications.

Simplicity is the highest form of sophistication.

Perfection is achieved by eliminating unnecessary complexity.

Related resources:

KISS principle – https://en.wikipedia.org/wiki/KISS_principle

Keep It Simple Stupid – http://principles-wiki.net/principles:keep_it_simple_stupid

YAGNI

"You Aren't Gonna Need It": do not implement features before they are actually required.

Why

Working on future‑only features diverts effort from current goals.

It inflates code, making software larger and more complex.

How

Implement features only when you truly need them, not when you anticipate a need.

Related resources:

You Aren't Gonna Need It – http://c2.com/xp/YouArentGonnaNeedIt.html

You’re NOT gonna need it! – http://www.xprogramming.com/Practices/PracNotNeed.html

You ain’t gonna need it – http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it

Do the Simplest Thing

Ask yourself: "What is the simplest thing that could possibly work?"

Related resource:

Do The Simplest Thing That Could Possibly Work – http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html

Separation of Concerns

Divide a program into distinct parts, each focusing on a single concern (e.g., business logic vs. UI). Changes to one part should not require changes to the other.

Quote from Edsger W. Dijkstra (1974): "I sometimes call it ‘separation of concerns’, even though it cannot be achieved perfectly, it is the only effective mental‑organising technique I know. It means focusing on one aspect while ignoring others, not that the ignored aspects are unimportant."

Why

Simplifies development and maintenance.

Well‑separated concerns enable reuse and independent evolution.

How

Split functionality into as few modules as possible, each with a clear responsibility.

Related resource:

Separation of Concerns – https://en.wikipedia.org/wiki/Separation_of_concerns

Don’t Repeat Yourself (DRY)

Each piece of knowledge should have a single, authoritative representation within a system.

Why:

Duplication leads to maintenance nightmares, inconsistencies, and logical contradictions.

Modifying one element should not require changes to unrelated parts.

Related logic changes become predictable and uniform.

How:

Write business rules, long expressions, if‑statements, formulas, metadata, etc., in only one place.

Identify the single source of truth for each concept and generate all required artifacts from it.

Apply the Rule of Three – http://en.wikipedia.org/wiki/Rule_of_three_(computer_programming)

Related resources:

Don’t Repeat Yourself – http://c2.com/cgi/wiki?DontRepeatYourself

DRY Wikipedia – http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

DRY O'Reilly – http://programmer.97things.oreilly.com/wiki/index.php/Don%27t_Repeat_Yourself

Write Code for the Maintainer

Maintenance is the most expensive phase of any project.

How:

Think of the future maintainer as a person who knows where they live and is a bit crazy – write code that is pleasant to read.

Make the code and comments enjoyable for newcomers.

Don’t Make Me Think – http://www.sensible.com/dmmt.html

Principle of Least Astonishment – http://en.wikipedia.org/wiki/Principle_of_least_astonishment

Related resources:

Code For The Maintainer – http://c2.com/cgi/wiki?CodeForTheMaintainer

The Noble Art of Maintenance Programming – http://blog.codinghorror.com/the-noble-art-of-maintenance-programming/

Avoid Premature Optimization

Programmers waste time optimizing non‑critical parts, which harms debugging and maintenance. As Donald Knuth said, 97% of development time should ignore low‑efficiency; only the critical 3% deserves optimization.

Why:

The bottleneck is unknown.

Optimizing early can make code harder to read and maintain.

How:

Make it work, make it right, then make it fast – http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast

Only optimize after identifying a real bottleneck.

Related resources:

Program optimization – http://en.wikipedia.org/wiki/Program_optimization

Premature Optimization – http://c2.com/cgi/wiki?PrematureOptimization

Minimize Coupling

Coupling measures how much modules depend on each other; lower coupling is better.

Why:

Changes in one module can ripple to others.

Higher dependency increases assembly effort.

Highly coupled modules are harder to reuse and test.

Developers may fear changes due to unknown impact.

How:

Eliminate, minimize, and reduce unnecessary connections.

Hide implementation details to lower coupling.

Apply the Law of Demeter – https://mouse0w0.github.io/2018/10/04/Programming-Principles/#%E8%BF%AA%E7%B1%B3%E6%B3%95

Related resources:

Coupling – http://en.wikipedia.org/wiki/Coupling_(computer_programming)

Coupling and Cohesion – http://c2.com/cgi/wiki?CouplingAndCohesion

Law of Demeter

"Talk only to your immediate friends." Avoid talking to strangers.

Why:

Prevents tight coupling.

Reduces exposure of implementation details.

How:

Only call methods of the object itself.

Only call methods of objects passed as parameters.

Only call methods of objects created within the method.

Only call methods of the object's direct fields.

Related resources:

Law of Demeter – http://en.wikipedia.org/wiki/Law_of_Demeter

Law of Demeter is not a dot‑counting exercise – http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx/

Composition Over Inheritance

Why:

Reduces coupling between classes.

Inheritance can break the Liskov Substitution Principle.

How:

Test LSP to decide when inheritance is appropriate.

Use composition when a "has" relationship exists; use inheritance for an "is" relationship.

Related resource:

Favor Composition Over Inheritance – http://blogs.msdn.com/b/thalesc/archive/2012/09/05/favor-composition-over-inheritance.aspx

Orthogonality

The basic idea of orthogonality is that unrelated concepts should not be related in a system.

Source: Be Orthogonal – http://www.artima.com/intv/dry3.html

The simpler the design, the fewer exceptions, making learning and reading code easier. Orthogonal features are independent of environment; key parameters are symmetry and consistency.

Source: Orthogonality

Robustness Principle

Be conservative in what you do, be liberal in what you accept from others.

Cooperating services depend on each other's interfaces. Providers should evolve without breaking existing clients.

Why:

To evolve a service, ensure changes support new needs while minimizing impact on existing clients.

How:

Code that sends commands or data must strictly follow the specification, while code that receives should tolerate reasonable deviations.

Related resources:

Robustness Principle – https://en.wikipedia.org/wiki/Robustness_principle

Tolerant Reader – http://martinfowler.com/bliki/TolerantReader.html

Inversion of Control

Also known as the Hollywood Principle: "Don’t call us, we’ll call you." Custom code receives control flow from a generic framework, improving modularity and extensibility.

Why:

Increases module modularity and scalability.

Separates task execution from implementation.

Focuses modules on their design responsibilities.

Prevents modules from being constrained by assumptions about other systems.

Avoids side effects when swapping modules.

How:

Use the Factory pattern.

Use the Service Locator pattern.

Use Dependency Injection.

Use Dependency Lookup.

Use the Template Method pattern.

Use the Strategy pattern.

Related resources:

Inversion of Control – https://en.wikipedia.org/wiki/Inversion_of_control

IoC Containers and Dependency Injection – https://www.martinfowler.com/articles/injection.html

Maximize Cohesion

A module’s cohesion is the degree to which its responsibilities form a meaningful unit; higher cohesion is better.

Why:

Low cohesion makes understanding a module harder.

Changes in one part affect many others, increasing maintenance difficulty.

Unnecessary functionality hampers reuse.

How:

Group related functionality within a single class or component.

Related resources:

Cohesion – (general concept)

Coupling and Cohesion – http://c2.com/cgi/wiki?CouplingAndCohesion

Liskov Substitution Principle

Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.

Related resources:

Liskov Substitution Principle – http://en.wikipedia.org/wiki/Liskov_substitution_principle

LSP – http://www.blackwasp.co.uk/lsp.aspx

Open/Closed Principle

Software entities (e.g., classes) should be open for extension but closed for modification, allowing behavior changes without altering source code.

Why:

Improves maintainability and stability by minimizing changes to existing code.

How:

Write classes that can be extended rather than modified.

Expose only the parts that need to change; hide everything else.

Related resources:

Open Closed Principle – http://en.wikipedia.org/wiki/Open/closed_principle

The Open Closed Principle – https://8thlight.com/blog/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html

Single Responsibility Principle

A class should have only one reason to change.

Why:

Improves maintainability: only one module or class needs modification.

How:

Apply Curly’s Law (Do One Thing) – https://mouse0w0.github.io/2018/10/04/Programming-Principles/#%E7%A7%91%E9%87%8C%E5%AE%9A%E5%BE%8B

Related resource:

Single Responsibility Principle – http://en.wikipedia.org/wiki/Single_responsibility_principle

Information Hiding

Software modules expose interfaces while concealing implementation details.

Why:

Clients can remain unchanged when implementations evolve.

How:

Minimize the accessibility of classes and members.

Do not expose member data publicly.

Avoid leaking private implementation details into the class interface.

Reduce coupling to hide more implementation details.

Related resource:

Information Hiding – http://en.wikipedia.org/wiki/Information_hiding

Curly's Law (Rule of One)

Do one thing: each piece of code should have a single, well‑defined purpose.

Related resources:

Curly’s Law – http://blog.codinghorror.com/curlys-law-do-one-thing/

The Rule of One – http://fortyplustwo.com/2008/09/06/the-rule-of-one-or-curlys-law/

Encapsulate Varying Concepts

Identify concepts that are likely to change and encapsulate them behind stable interfaces.

Why:

Minimizes the amount of code that must be altered when a change occurs.

How:

Encapsulate varying concepts behind APIs.

Separate different concepts into their own modules.

Related resources:

Encapsulate the Concept that Varies – http://principles-wiki.net/principles:encapsulate_the_concept_that_varies

Encapsulate What Varies – http://blogs.msdn.com/b/steverowe/archive/2007/12/26/encapsulate-what-varies.aspx

Information Hiding – https://en.wikipedia.org/wiki/Information_hiding

Interface Segregation Principle

Reduce bulky interfaces into multiple smaller, client‑specific ones; interfaces should depend more on callers than on implementations.

Why:

If a class implements unnecessary methods, callers must understand those methods, even if they simply throw exceptions.

How:

Avoid fat interfaces; classes should not implement methods that violate the Single Responsibility Principle.

Related resource:

Interface Segregation Principle – https://en.wikipedia.org/wiki/Interface_segregation_principle

Boy Scout Rule

Leave the code cleaner than you found it, just like a Boy Scout leaves a campsite cleaner.

Why:

Each commit should not increase technical debt; small improvements prevent debt accumulation.

How:

Ensure every commit maintains or improves code quality.

Whenever you see unclear code, fix it immediately.

Related resource:

Opportunistic Refactoring – http://martinfowler.com/bliki/OpportunisticRefactoring.html

Command‑Query Separation

Methods should either perform an action (command) or return data (query), but not both. Queries must not change the answer.

Why:

Separating commands and queries lets programmers use queries confidently without side effects.

How:

Implement each method as either a query or a command.

Use naming conventions to indicate the method type.

Related resources:

Command Query Separation – https://en.wikipedia.org/wiki/Command–query_separation

Command Query Separation by Martin Fowler – http://martinfowler.com/bliki/CommandQuerySeparation.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

best practicessoftware designYAGNISOLIDprogramming principlesKISS
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.