Design Principles

Updated May 29, 2023#cs#patterns#principles

These principles establish practices that lend to developing software with considerations for maintaining and extending as the project grows. Adopting these practices can also contribute to avoiding code smells, refactoring code, and Agile or Adaptive software development.


  • The single-responsibility principle: “There should never be more than one reason for a class to change.” In other words, every class should have only one responsibility.
  • The open–closed principle: “Software entities … should be open for extension, but closed for modification.”
  • The Liskov substitution principle: “Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.” See also design by contract.
  • The interface segregation principle: “Many client-specific interfaces are better than one general-purpose interface.”
  • The dependency inversion principle: “Depend upon abstractions, not concretions.”


“Don’t repeat yourself” (DRY) is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.

The DRY principle is stated as “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”.

When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.


KISS, an acronym for keep it simple stupid, is a design principle noted by the U.S. Navy in 1960.

The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided.


“You aren’t gonna need it” (YAGNI) is a principle which arose from extreme programming (XP) that states a programmer should not add functionality until deemed necessary.

It is meant to be used in combination with several other practices, such as continuous refactoring, continuous automated unit testing, and continuous integration. Used without continuous refactoring, it could lead to disorganized code and massive rework, known as technical debt. YAGNI’s dependency on supporting practices is part of the original definition of XP.