C#/기초

SOLID원칙

도도돋치 2025. 4. 13. 20:00
Contents 접기
728x90

팀원분들과 얘기하다가 디자인패턴 중, SOLID원칙에 대해 알게되었다.

 

SOLID 원칙이란?

5가지 객체지향 설계 원칙의 앞 글자를 따서 만든 말이다.

객체지향 프로그래밍(OOP)에서 유지보수성과 확장성을 높이기 위한 디자인 원칙

원칙이름 핵심 개념 설명
S: SRP 단일 책임 원칙 클래스는 하나의 책임만 가져야 함
O: OCP 개방-폐쇄 원칙 확장에는 열려 있고, 수정에는 닫혀 있어야 함
L: LSP 리스코프 치환 원칙 자식 클래스는 부모 클래스를 대체할 수 있어야 함
I: ISP 인터페이스 분리 원칙 사용하지 않는 기능에 의존하지 않도록 인터페이스는 작게 나눠야 함
D: DIP 의존성 역전 원칙 고수준 모듈은 저수준 모듈에 의존하지 않고, 추상화에 의존해야 함

 

SRP (Single Responsibility Principle)

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

 

X) 게시물 클래스가 DB 저장 + 화면 표시 + 로그 기록 전부 다 함
O) 각각 분리해서 책임을 나눔 (저장, UI, 로깅 클래스 따로)

 

OCP (Open/Closed Principle)

코드는 확장에는 열려 있고, 수정에는 닫혀 있어야 한다.

 

기능 추가 시 기존 코드 수정하지 않고, 새로운 클래스를 추가해 확장하는 방식이 좋음.

 

LSP (Liskov Substitution Principle)

부모 클래스를 사용하는 곳에 자식 클래스도 문제없이 대체할 수 있어야 함.

 

예) Bird 클래스 → Penguin이 상속받았는데, Fly() 메서드를 오버라이드해서 에러 발생하면 위반

 

ISP (Interface Segregation Principle)

큰 인터페이스 하나보다, 작은 인터페이스 여러 개로 나누는 게 좋다.

interface IPrinter { void Print(); }
interface IScanner { void Scan(); }

프린터만 필요한 클래스가 스캐너 기능까지 강제로 구현하지 않아도 됨.

 

DIP (Dependency Inversion Principle)

구체 클래스에 의존 X인터페이스나 추상 클래스에 의존해야 한다

// 나쁜 예
class EmailSender {
    public void SendEmail() { ... }
}
class User {
    private EmailSender sender = new EmailSender(); // 직접 의존
}
  • User 클래스가 EmailSender라는 구체적인 구현에 묶여있음
  • 바꾸고 싶어도 고치기 어려움 (예: 카카오톡 보내기로 바꾸고 싶을 때 User도 뜯어고쳐야 함)
// 1. 역할(인터페이스)을 정의
interface IMessageSender {
    void Send();
}

// 2. 다양한 구현체들
class EmailSender : IMessageSender {
    public void Send() {
        Console.WriteLine("이메일을 보냈습니다.");
    }
}

class KakaoSender : IMessageSender {
    public void Send() {
        Console.WriteLine("카카오톡 메시지를 보냈습니다.");
    }
}

// 3. User는 메시지 전송 방식에 대해 모름. 역할만 알면 됨
class User {
    private IMessageSender sender;

    public User(IMessageSender sender) {
        this.sender = sender;
    }

    public void Notify() {
        sender.Send();
    }
}
  • User IMessageSender라는 역할(추상화)만 알고 있음
  • EmailSender든, KakaoSender든 어떤 구현이 와도 동작은 같음
  • 새로운 전송 방식이 생겨도 User는 그대로 사용 가능

+) C#에서 : 기호는 인터페이스에도 쓰인다.

인터페이스는 "보내는 기능이 있는 애들만 와" 라고 약속하는 기능 계약서이다. 이를 기반으로, 여러가지 보내는 방법을 구현할 수 있다.

 

🔹이 패턴을 활용하면?

-> KakaoSender, SMSSender, PushSender 등 다양한 클래스 추가해도 User는 변경할 필요가 없다.

728x90

'C# > 기초' 카테고리의 다른 글

[C#] 객체지향 프로그래밍  (0) 2025.04.17
[C#] 접근 제한자와 반환 타입  (0) 2025.04.17
[C#] C#개념  (0) 2025.04.14