[Java] 객체지향설계의 5가지 원칙 (SOLID 원칙)

2025. 8. 3. 15:46·Java

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

한 클래스는 하나의 책임만 가져야 한다. 한 클래스가 너무 많은 일을 하게 되면 유지보수가 어려워진다. 

예시

  • 잘못된 예 : 하나의 클래스가 '보고서 생성' , '출력' , '이메일 발송' 책임까지 모두 담당한다. 
class ReportService {
    void generateReport() { /* 보고서 데이터 생성 */ }
    void printReport() { /* 보고서 출력 */ }
    void sendReportByEmail() { /* 보고서 이메일 발송 */ }
}
  • 개선 : 각 클래스가 한 가지 책임만 맡는다. 
class ReportGenerator { void generate() { /* 보고서 생성 */ } }
class ReportPrinter { void print() { /* 보고서 출력 */ } }
class EmailSender { void send() { /* 이메일 발송 */ } }

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

확장에는 열려 있고, 변경에는 닫혀 있어야 한다. 기능을 추가할 때 기존 코드를 수정하지 않고, 새로운 코드를 추가하도록 설계한다. 

예시 

  • 잘못된 예 : 새로운 결제 방식 추가 시 `if 문` 을 계속 수정해야한다. 
class PaymentService {
    void pay(String type) {
        if ("CARD".equals(type)) { /* 카드 결제 */ }
        else if ("KAKAO".equals(type)) { /* 카카오페이 */ }
    }
}
  • 개선 : 새로운 결제 수단 추가 시 기존 코드 변경 없이 클래스만 추가한다. 
interface Payment {
    void pay();
}

class CardPayment implements Payment {
    public void pay() { /* 카드 결제 */ }
}

class KakaoPayment implements Payment {
    public void pay() { /* 카카오페이 */ }
}

class PaymentService {
    void pay(Payment payment) {
        payment.pay(); // 새로운 결제방식 추가해도 PaymentService 수정 없음
    }
}

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

부모 타입의 객체를 자식 타입으로 바꿔도 프로그램이 정상 동작해야 한다. 자식 클래스는 부모 클래스의 기능을 완전히 대체 가능해야 한다. 

예시 

  • 잘못된 예 : 타조는 날지 못하는데, 부모 (Bird)는 날 수 있다고 가정
class Bird { void fly() {} }
class Ostrich extends Bird { 
    void fly() { throw new UnsupportedOperationException(); }
}
  • 개선 : 날 수 있는 새와 없는 새를 분리하여 자식 클래스가 부모의 계약을 어기지 않도록 함 
interface Bird {}
interface FlyableBird extends Bird { void fly(); }

class Sparrow implements FlyableBird { public void fly() {} }
class Ostrich implements Bird { /* 날 수 없는 새 */ }

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

하나의 큰 인터페이스보다, 여러 개의 구체적이고 작은 인터페이스가 낫다. 사용하지 않는 메서드까지 구현하게끔 하면 안된다. 

예시 

  • 잘못된 예 : 프린터인데 스캔/팩스 메서드까지 구현 강제 
interface Machine {
    void print();
    void scan();
    void fax();
}

class SimplePrinter implements Machine {
    public void print() {}
    public void scan() { /* 필요 없음 */ }
    public void fax() { /* 필요 없음 */ }
}
  • 개선 : 필요한 기능만 구현하도록 인터페이스 분리 
interface Printer { void print(); }
interface Scanner { void scan(); }

class SimplePrinter implements Printer {
    public void print() {}
}

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

구현 클래스가 아니라, 추상화에 의존해야한다. 상위 모듈이 하위 모듈에 의존하면 결합도가 높아지고 변경에 취약하다. 

예시 

  • 잘못된 예 : Computer 클래스가 특정 Keyboard, Monitor 클래스에 강하게 의존한다. 
class Keyboard {}
class Monitor {}

class Computer {
    private Keyboard keyboard = new Keyboard();
    private Monitor monitor = new Monitor();
}
  • 개선 : 인터페이스에 의존하므로 구현체 변경 시 코드 수정 필요 없음 
interface Keyboard {}
interface Monitor {}

class LogitechKeyboard implements Keyboard {}
class SamsungMonitor implements Monitor {}

class Computer {
    private Keyboard keyboard;
    private Monitor monitor;

    public Computer(Keyboard keyboard, Monitor monitor) {
        this.keyboard = keyboard;
        this.monitor = monitor;
    }
}

'Java' 카테고리의 다른 글

[Java] 자바 변수 4가지 정리 (전역, 지역, 정적, 멤버 변수)  (0) 2025.11.10
[Java] 원시타입(Primitive Type)과 참조타입(Reference Type)  (0) 2025.10.14
[Java] 스트림(Stream)에 대하여  (0) 2025.10.14
[Java] 실수를 나타내는 Double, double, float, decimal 의 차이  (0) 2025.10.13
[Java] POJO(Plain Old Java Object)  (0) 2025.09.16
'Java' 카테고리의 다른 글
  • [Java] 원시타입(Primitive Type)과 참조타입(Reference Type)
  • [Java] 스트림(Stream)에 대하여
  • [Java] 실수를 나타내는 Double, double, float, decimal 의 차이
  • [Java] POJO(Plain Old Java Object)
erika0915
erika0915
백엔드 개발자가 되고 싶어요 .
  • erika0915
    erikoding
    erika0915
  • 전체
    오늘
    어제
    • 분류 전체보기 (78)
      • 프로젝트 (13)
        • 끼니콩 (3)
        • 덕메랑 (3)
        • handDoc (7)
        • Haeil (0)
      • Java (9)
        • 클린코더스 (0)
      • Spring (30)
      • Redis (3)
      • CS (7)
        • 운영체제 (3)
        • 컴퓨터구조 (0)
        • 네트워크 (4)
      • DevOps (2)
      • 코딩테스트 (0)
      • Tech (14)
        • TDD (1)
        • 정리 (5)
        • 우테코 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CoolSMS
    AI
    redis
    Network
    jira
    지라
    promtail
    코드레빗
    springboot
    MongoDB
    TDD
    java
    STT
    도커
    github
    OS
    운영체제
    자바
    파인튜닝
    coderabbit
    네트워크
    레디스
    깃허브
    스프링
    docker
    Spring
    git
    스프링부트
    깃
    몽고디비
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
erika0915
[Java] 객체지향설계의 5가지 원칙 (SOLID 원칙)

티스토리툴바