Design Principles
- DRY - Don’t Repeat Yourself
- KISS - Keep It Simple and Stupid
- YAGNI - You Ain’t Gonna Need It
- SoC - Separation of Concerns
- Favor Composition over Inheritance
- Program to Interface, not Implementation
1. DRY (Don’t Repeat Yourself)
Section titled “1. DRY (Don’t Repeat Yourself)”Explanation
Section titled “Explanation”DRY is a principle aimed at reducing code duplication by ensuring that each piece of knowledge or logic is represented in a single place. This makes the code more maintainable and less prone to errors.
Example
Section titled “Example”Bad Practice (Violation of DRY):
class Employee { private String name; private double salary;
public double calculateBonus() { return salary * 0.1; // Bonus calculation logic duplicated }}
class Manager extends Employee { public double calculateBonus() { return getSalary() * 0.1; // Same logic repeated }}Good Practice (Following DRY):
class Employee { private String name; private double salary;
public double calculateBonus() { return salary * 0.1; }}
class Manager extends Employee { // No duplication; reuses the calculateBonus method}2. KISS (Keep It Simple and Stupid)
Section titled “2. KISS (Keep It Simple and Stupid)”Explanation
Section titled “Explanation”KISS encourages writing simple, easy-to-understand code rather than overcomplicating logic with unnecessary complexity.
Example
Section titled “Example”Bad Practice (Violation of KISS):
if (isUserLoggedIn && (userRole.equals("ADMIN") || userRole.equals("MODERATOR")) && isNotBanned) { grantAccess();}Good Practice (Following KISS):
boolean hasAccess = isUserLoggedIn && (isAdmin() || isModerator()) && isNotBanned;if (hasAccess) { grantAccess();}3. YAGNI (You Ain’t Gonna Need It)
Section titled “3. YAGNI (You Ain’t Gonna Need It)”Explanation
Section titled “Explanation”YAGNI suggests that you should not add functionality until it is actually needed. This helps avoid unnecessary complexity and reduces maintenance overhead.

Example
Section titled “Example”Bad Practice (Violation of YAGNI):
class User { private String username; private String email; private String phoneNumber; // Added without requirement private String address; // Added without requirement}Good Practice (Following YAGNI):
class User { private String username; private String email; // Only required fields included}4. SoC (Separation of Concerns)
Section titled “4. SoC (Separation of Concerns)”Explanation
Section titled “Explanation”Separation of Concerns (SoC) means that a software system should be divided into distinct sections, each handling a specific responsibility.
Example
Section titled “Example”Bad Practice (Violation of SoC):
class UserManager { public void saveUser(User user) { // Database logic }
public void sendEmail(User user) { // Email sending logic }}Good Practice (Following SoC):
class UserRepository { public void save(User user) { // Database logic }}
class EmailService { public void sendEmail(User user) { // Email sending logic }}5. Favor Composition over Inheritance
Section titled “5. Favor Composition over Inheritance”- Description: Prefer combining objects through composition rather than creating class hierarchies through inheritance.
- Example: Instead of creating a deep inheritance tree of different types of
Animal(e.g.,Dog,Cat,Bird), use composition to give animals behaviour’s likeSpeakable,Flyable,Swimmable.
Example
Section titled “Example”Instead of:
Section titled “Instead of:”class Animal { }class Mammal extends Animal { }class Dog extends Mammal { }class Cat extends Mammal { }interface Speakable { void speak();}
class Dog implements Speakable { public void speak() { System.out.println("Woof!"); }}Explanation
Section titled “Explanation”Instead of using inheritance (which creates rigid hierarchies), favor composition to make code more flexible and maintainable.

Example
Section titled “Example”Bad Practice (Violation of Composition Over Inheritance):
class Engine { public void start() { System.out.println("Engine started"); }}
class Car extends Engine { public void drive() { start(); System.out.println("Car is driving"); }}Good Practice (Following Composition Over Inheritance):
class Engine { public void start() { System.out.println("Engine started"); }}
class Car { private Engine engine;
public Car(Engine engine) { this.engine = engine; }
public void drive() { engine.start(); System.out.println("Car is driving"); }}6. Program to Interface, Not Implementation
Section titled “6. Program to Interface, Not Implementation”- Description: Write code that depends on interfaces or abstract classes, not concrete classes.
- Example: Use an interface like
Listinstead of a concrete class likeArrayListwhen declaring variables and passing arguments.- Instead of:
ArrayList<String> myList = new ArrayList<>(); - Do:
List<String> myList = new ArrayList<>();
- Instead of:
Example
Section titled “Example”Bad Practice (Violation of this Principle):
class MySQLDatabase { public void connect() { System.out.println("Connecting to MySQL"); }}
class Application { private MySQLDatabase database;
public Application(MySQLDatabase database) { this.database = database; }
public void start() { database.connect(); }}Good Practice (Following the Principle):
interface Database { void connect();}
class MySQLDatabase implements Database { public void connect() { System.out.println("Connecting to MySQL"); }}
class Application { private Database database;
public Application(Database database) { this.database = database; }
public void start() { database.connect(); }}