✅ SOLID 원칙이란?

졸용·2025년 3월 28일

✅ SOLID 원칙이란?

객체 지향 설계의 5가지 기본 원칙, 소프트웨어 설계에서 유지보수성, 확장성, 유연성을 높이기 위한 지침을 제공한다.


✅ SOLID 원칙의 종류

  1. 단일 책임 원칙 SRP(Single Responsibility Principle)

  2. 개방 폐쇄 원칙 OCP(Open Closed Principle)

  3. 리스코프 치환 원칙 LSP(Liskov Substitution Principle)

  4. 인터페이스 분리 원칙 ISP(Interface Segregation Principle)

  5. 의존관계 역전 원칙 DIP(Dependency Inversion Principle)


1️⃣ 단일 책임 원칙 SRP(Single Responsibility Principle)

  • ❗하나의 클래스는 하나의 책임만 가져야 한다.❗

  • 변경이 발생할 이유가 하나뿐이어야 한다.

(예) 사용자 정보를 저장하는 User 클래스가 데이터를 출력하는 역할까지 하면 안 되고, 출력은 별도의 UserPrinter 클래스가 담당해야 한다.


2️⃣ 개방 폐쇄 원칙 OCP(Open Closed Principle)

  • ❗확장에는 열려 있어야 하지만, 변경에는 닫혀 있어야 한다.❗

  • 새로운 기능을 추가할 때 기존 코드를 수정하지 말고 확장해야 한다.

(예) Shape 인터페이스를 만들고 Rectangle, Circle 등이 이를 구현하면, 새로운 도형을 추가할 때 기존 코드를 수정할 필요가 없다.


3️⃣ 리스코프 치환 원칙 LSP(Liskov Substitution Principle)

  • ❗자식 클래스는 언제나 부모 클래스를 대체할 수 있어야 한다.❗

  • 부모 클래스의 기능을 하위 클래스가 확장할 수 있지만, 동작을 변경해서는 안 된다.

(예) Bird 클래스를 상속받은 Penguin 클래스가 fly() 메서드를 가지면 안 된다. 대신 Flyable 인터페이스를 만들어서 필요한 클래스에만 적용해야 한다.


4️⃣ 인터페이스 분리 원칙 ISP(Interface Segregation Principle)

  • ❗하나의 거대한 인터페이스보다, 작은 여러 개의 인터페이스로 나누는 것이 좋다.❗

  • 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.

(예) Animal 인터페이스가 run(), fly(), swim()을 모두 포함하면, 모든 동물 클래스가 필요하지 않은 기능까지 구현해야 한다. → Runnable, Flyable, Swimmable로 분리하는 것이 좋다.


5️⃣ 의존관계 역전 원칙 DIP(Dependency Inversion Principle)

  • 상위(추상) 모듈이 하위(구현) 모듈에 의존하면 안 된다.

  • 즉, ❗구체적인 클래스에 의존하지 말고, 인터페이스나 추상 클래스에 의존하도록 설계해야 한다.❗

(예) connect() 메서드를 가지는 WiredMouse 클래스와 WiredKeyboard 클래스를 의존하면 나중에 WirelessMouseWirelessKeyboard 에 대한 코드의 수정이 필요해진다.

구체적이기 보다는 추상적인 인터페이스를 의존하는 것이 좋다.

connect() 메서드를 가지는 Mouse 인터페이스와 Keyboard 인터페이스를 의존하면 의존성이 줄어들고 유지보수성이 높아진다.

// 1. 인터페이스 정의 (추상화)
interface Keyboard {
    void connect();
}

interface Mouse {
    void connect();
}

// 2. 유선 키보드 & 무선 키보드 구현
class WiredKeyboard implements Keyboard {
    public void connect() {
        System.out.println("유선 키보드 연결됨");
    }
}

class WirelessKeyboard implements Keyboard {
    public void connect() {
        System.out.println("무선 키보드 연결됨");
    }
}

// 3. 유선 마우스 & 무선 마우스 구현
class WiredMouse implements Mouse {
    public void connect() {
        System.out.println("유선 마우스 연결됨");
    }
}

class WirelessMouse implements Mouse {
    public void connect() {
        System.out.println("무선 마우스 연결됨");
    }
}

// 4. Computer 클래스가 "구체적인 키보드/마우스"가 아닌 "추상적인 인터페이스"에 의존!
class Computer {
    private Keyboard keyboard;
    private Mouse mouse;

    public Computer(Keyboard keyboard, Mouse mouse) {
        this.keyboard = keyboard;  // 추상화된 인터페이스에 의존!
        this.mouse = mouse;  // 추상화된 인터페이스에 의존!
    }

    void start() {
        keyboard.connect();
        mouse.connect();
    }
}

public class Main {
    public static void main(String[] args) {
        // 원하는 장치를 자유롭게 변경 가능!
        Keyboard myKeyboard = new WirelessKeyboard();  // 무선 키보드 선택
        Mouse myMouse = new WiredMouse();  // 유선 마우스 선택

        Computer myComputer = new Computer(myKeyboard, myMouse);
        myComputer.start();
    }
}
profile
꾸준한 공부만이 답이다

0개의 댓글