
한 클래스는 하나의 책임만 가져야 한다. (변경 이유는 단 하나)
위반
class ReportGenerator {
public void generateReport() { System.out.println("Generating..."); }
public void saveToFile(String fileName) { System.out.println("Saving: " + fileName); }
}
적용
class ReportGenerator {
public void generateReport() { System.out.println("Generating..."); }
}
class ReportSaver {
public void saveToFile(String fileName) { System.out.println("Saving: " + fileName); }
}
체크리스트
확장에는 열려 있고, 변경에는 닫혀 있어야 한다.
위반
class DiscountCalculator {
double calculateDiscount(String type, double price) {
if (type.equals("Regular")) return price * 0.1;
else if (type.equals("VIP")) return price * 0.2;
return 0;
}
}
적용 (전략 패턴)
interface DiscountStrategy { double applyDiscount(double price); }
class RegularDiscount implements DiscountStrategy {
public double applyDiscount(double price) { return price * 0.1; }
}
class VIPDiscount implements DiscountStrategy {
public double applyDiscount(double price) { return price * 0.2; }
}
class DiscountCalculator {
double calculateDiscount(DiscountStrategy strategy, double price) {
return strategy.applyDiscount(price);
}
}
체크리스트
if/else로 타입 분기가 늘어나는가? → 다형성으로 치환하위 타입은 상위 타입을 대체할 수 있어야 한다.
위반 (못 나는 펭귄)
class Bird { public void fly() { System.out.println("flying"); } }
class Penguin extends Bird {
@Override public void fly() { throw new UnsupportedOperationException(); }
}
적용 (타입 분리)
interface FlyingBird { void fly(); }
class Sparrow implements FlyingBird {
public void fly() { System.out.println("Sparrow flying"); }
}
class Penguin {
public void swim() { System.out.println("Penguin swimming"); }
}
체크리스트
클라이언트는 사용하지 않는 메서드에 의존하지 않아야 한다.
위반 (불필요한 메서드 강제)
interface Worker { void work(); void eat(); }
class Robot implements Worker {
public void work() { System.out.println("Robot working"); }
public void eat() { throw new UnsupportedOperationException(); }
}
적용 (인터페이스 분리)
interface Workable { void work(); }
interface Eatable { void eat(); }
class Robot implements Workable {
public void work() { System.out.println("Robot working"); }
}
class Human implements Workable, Eatable {
public void work() { System.out.println("Human working"); }
public void eat() { System.out.println("Human eating"); }
}
체크리스트
상위/하위 모듈 모두 구체가 아닌 추상에 의존해야 한다.
(구체 생성은 외부에서 주입)
위반
class MechanicalKeyboard { void type() { System.out.println("Mech..."); } }
class Computer {
private MechanicalKeyboard keyboard = new MechanicalKeyboard();
void useKeyboard() { keyboard.type(); }
}
적용 (인터페이스 + DI)
interface Keyboard { void type(); }
class MechanicalKeyboard implements Keyboard {
public void type() { System.out.println("Mech..."); }
}
class WirelessKeyboard implements Keyboard {
public void type() { System.out.println("Wireless..."); }
}
class Computer {
private final Keyboard keyboard;
public Computer(Keyboard keyboard) { this.keyboard = keyboard; } // 생성자 주입
public void useKeyboard() { keyboard.type(); }
}
체크리스트