Skip to content
Dev Dump

Design Principles - II

  1. Law of Demeter (LoD)
  2. Boy Scout Rule
  3. Code for the Maintainer
  4. Principle of Least Astonishment (POLA)
  5. Tight Coupling vs. Loose Coupling
  6. Minimize Coupling & Maximize Cohesion
  • Description: An object should only talk to its immediate neighbours. Avoid long chains of method calls.
  • Example: A Car object should not directly access the Engine’s Piston object. Instead, Car should ask the Engine to perform operations on the Piston. - Instead of: car.getEngine().getPiston().move(); - Do: car.startEngine(); (where startEngine encapsulates the necessary interactions within the Engine class).
  • A method should call only:
    • Its own methods
    • Methods on objects it creates
    • Methods on objects passed to it
    • Methods on its member variables

Law of Demeter illustration

class Engine {
public void start() {
System.out.println("Engine started");
}
}
class Car {
private Engine engine;
public Car() {
this.engine = new Engine();
}
public Engine getEngine() {
return engine;
}
}
class Driver {
public void startCar(Car car) {
car.getEngine().start(); // Violates LoD
}
}
class Car {
private Engine engine;
public Car() {
this.engine = new Engine();
}
public void start() {
engine.start(); // Encapsulation
}
}
class Driver {
public void startCar(Car car) {
car.start(); // Follows LoD
}
}

“Always leave the code better than you found it.”

  • Refactor code when necessary.
  • Improve readability and maintainability.
  • Remove duplicate or unused code.

Boy Scout Rule

Before applying the Boy Scout Rule:

class User {
public String firstName;
public String lastName;
}

After refactoring:

class User {
private String firstName;
private String lastName;
public String getFullName() {
return firstName + " " + lastName;
}
}

Write code that is readable, self-explanatory, and well-documented for future maintainers.

  • Use meaningful variable/method names.
  • Write clear comments.
  • Avoid complex logic when possible.
  • Follow coding conventions.

Poorly written code:

class C {
int x;
int y;
void p() {
x = 10;
y = 20;
System.out.println(x + y);
}
}

Refactored, readable code:

class Calculator {
private int firstNumber;
private int secondNumber;
public void setNumbers(int a, int b) {
this.firstNumber = a;
this.secondNumber = b;
}
public void printSum() {
System.out.println(firstNumber + secondNumber);
}
}

The system should behave in a way that minimizes surprises for users and developers.

Principle of Least Astonishment

class LightSwitch {
public void toggle() {
System.out.println("Fan turned ON"); // Unexpected behavior
}
}
class LightSwitch {
private boolean isOn = false;
public void toggle() {
isOn = !isOn;
System.out.println(isOn ? "Light turned ON" : "Light turned OFF");
}
}
  • Tightly Coupled: Classes depend heavily on each other.
  • Loosely Coupled: Classes have minimal dependencies and interact via interfaces.
class EmailService {
public void sendEmail(String message) {
System.out.println("Email sent: " + message);
}
}
class Notification {
private EmailService emailService = new EmailService();
public void notifyUser() {
emailService.sendEmail("Hello User");
}
}
interface MessageService {
void sendMessage(String message);
}
class EmailService implements MessageService {
public void sendMessage(String message) {
System.out.println("Email sent: " + message);
}
}
class Notification {
private MessageService messageService;
public Notification(MessageService messageService) {
this.messageService = messageService;
}
public void notifyUser() {
messageService.sendMessage("Hello User");
}
}
  • Minimizing Coupling: Reduce dependencies between modules.
  • Maximizing Cohesion: Keep related functionalities together.
class Employee {
String name;
int age;
public void calculateSalary() {
// Salary calculation logic (Unrelated responsibility)
}
}
class Employee {
String name;
int age;
}
class SalaryCalculator {
public double calculateSalary(Employee emp) {
// Properly encapsulated salary logic
return 50000.0;
}
}
PrincipleKey Idea
Law of DemeterReduce unnecessary dependencies
Boy Scout RuleLeave the code cleaner than you found it
Code for the MaintainerWrite readable and maintainable code
Principle of Least AstonishmentAvoid unexpected behavior in code
Tight Coupling vs. Loose CouplingPrefer loose coupling using interfaces
Minimize Coupling & Maximize CohesionReduce dependencies, keep related logic together