구어체로 설명하는 다이어리

객체 지향 설계 원칙 (SOLID) 이란? 본문

스터디/요구사항 확인

객체 지향 설계 원칙 (SOLID) 이란?

씨씨상 2025. 1. 15. 18:31

 

 

객체 지향 설계 원칙(SOLID)에 대해서 들어는 봤지만, 각각의 내용을 잘 파악하지 못하고 있던 것 같아 정리해보았습니다. SOLID는 다음의 5가지 원칙의 앞글자를 따서 지칭한 것입니다.

 

 

SOLID란...

 

 

  • 단일 책임 원칙 (Single Responsibility Principle)
  • 개방-폐쇄 원칙 (Open/Closed Principle)
  • 리스코프 치환 원칙 (Liskov Substitution Principle)
  • 인터페이스 분리 원칙 (Interface Segregation Principle)
  • 의존 관계 역전 원칙 (Dependency Inversion Principle)

 

이렇게 5가지 원칙을 말합니다. 그럼 하나하나 알아봅시다.

 

 

 

단일 책임 원칙

 

 

단일 책임 원칙은 하나의 클래스는 하나의 책임을 져야 한다는 원칙입니다. 여기서 책임은 하나의 기능 담당이라고 보면 됩니다. 결국 하나의 클래스는 하나의 기능을 담당하여 하나의 책임을 수행하는데 집중하도록 클래스를 따로따로 설계하라는 의미입니다.

식당 같은 곳을 예로 들면, 주방 직원과 홀 직원으로 나뉘어 진 것을 볼 수 있겠네요. 하나의 직원이 음식도 만들고 서빙도 하고 계산도 한다면 너무 혼란스럽고 복잡하며 실수를 야기할 겁니다. 그렇기 때문에 주방 직원은 음식을 만드는 데에만 힘쓰고, 홀 직원은 손님 응대에만 집중함으로써 책임을 나누어 지는 것입니다. 프로그램도 클래스 별로 구분하여 설계할 경우 더 효율성있는 구성이 되겠죠.

 

 

 

개방-폐쇄 원칙

 

 

개방-폐쇄 원칙은 클래스는 확장에는 열려 있어야 하고 수정에는 닫혀 있어야 한다는 원칙입니다. 이것은 말 그대로 기존 시스템을 수정하지 않고 확장하라는 뜻입니다.

카페 메뉴판 같은 것을 생각해 볼까요. 뜨거운 아메리카노가 3000원이고 뜨거운 홍차가 4000원인 곳이 있습니다. 하지만 여름을 맞아 아이스 음료를 판매하려고 메뉴를 바꿨어요. 아이스 아메리카노 3500원, 아이스 홍차 4500원으로요. 이런 경우 다시 겨울이 되면 메뉴를 다시 원복해야 한다는 불편함이 있습니다. 그러니 메뉴를 수정하지 말고, 추가합시다. 뜨거운 아메리카노 3000원, 아이스 아메리카노 3500원, 뜨거운 홍차 4000원, 아이스 홍차 4500원으로 메뉴를 확장하면 기존 메뉴를 수정하지 않으면서 새로운 메뉴를 추가만 하면 됩니다. 코드를 매번 수정해줄 필요도 없으니 유연하게 동작합니다.

 

 

 

리스코프 치환 원칙

 

 

리스코프 치환 원칙은 자식 클래스는 언제든 부모 클래스를 대체할 수 있어야 한다는 원칙입니다. 이는 자식 클래스가 부모 클래스의 규약을 지키고 있다는 가정 하에 이루어지는 것인데요. 그렇다면 반대로 자식 클래스가 부모 클래스의 규약을 지키지 않아서 원칙이 깨지는 경우는 살펴보고 부모 클래스를 대체할 수 있다는 것이 어떤 의미인지 알아봅시다.

 

class Bird {
    fly(): string {
        return '나는 날고 있다.';
    }
}

class Penguin extends Bird {
    fly(): string {
        throw new Error('펭귄은 날 수 없다.');
    }
}

function BirdFlyLog(bird: Bird): void {
    console.log(bird.fly());
}

const penguin = new Penguin();
BirdFlyLog(penguin); //- Error: 펭귄은 날 수 없다.

 

Penguin은 자식 클래스이지만, 부모 클래스의 fly 메서드를 바르게 구현하지 않았기 때문에 리스코프 치환 원칙에 위반됩니다.

 

 

 

인터페이스 분리 원칙

 

 

인터페이스 분리 원칙은 쓸데 없는 인터페이스를 만들지 말라는 원칙입니다. 간단하게 말하면 필요한 기능만을 제공하자는 겁니다. 만약 여러분이 운전 학원에 갔는데 강사님께 수영이나 테니스를 알려주세요. 라고 하면 부자연스럽겠죠?

 

 

 

의존 관계 역전 원칙

 

 

의존 관계 역전 원칙은 변동성이 강한 클래스에 의존을 맺지 말라는 원칙입니다. 혹은 추상화(인터페이스)에 의존해야 한다고 볼 수 있겠네요. 되도록 쉽게 설명하려고 노력했으나 이 부분은 코드 없이 설명하기 어렵다고 여겨졌기 때문에 간단하게 첨부하겠습니다.

 

class Desktop {
    boot(): void {
        console.log('데스크탑 실행');
    }

    shutdown(): void {
        console.log('데스크탑 종료');
    }
}

class ComputerManager {
    private desktop: Desktop;

    constructor(desktop: Desktop) {
        this.desktop = desktop;
    }

    startComputer(): void {
        this.desktop.boot();
    }

    stopComputer(): void {
        this.desktop.shutdown();
    }
}

 

다음과 같이 ComputerManager가 Desktop에 의존하도록 만들면, 차후에 Desktop을 Laptop 등으로 바꾸고 싶을 때 ComputerManager를 수정해야 합니다. 반면 추상화된 개념 Computer를 만들면 어떨까요.

 

interface Computer {
    boot(): void;
    shutdown(): void;
}

class Desktop implements Computer {
    boot(): void {
        console.log('데스크탑 실행');
    }

    shutdown(): void {
        console.log('데스크탑 종료');
    }
}

class Laptop implements Computer {
    boot(): void {
        console.log('노트북 실행');
    }

    shutdown(): void {
        console.log('노트북 종료');
    }
}

class ComputerManager {
    private computer: Computer;

    constructor(computer: Computer) {
        this.computer = computer;
    }

    startComputer(): void {
        this.computer.bootOS();
    }

    stopComputer(): void {
        this.computer.shutdownOS();
    }
}

 

Desktop과 Laptop을 추상화한 개념 Computer에 ComputerManager를 의존함으로써 변경사항이 있어도 코드를 수정하지 않고 추가하는 것으로 마무리할 수 있게 되었습니다.

 

 

 

 

 

[참고자료]

참고자료1

 

객체 지향 설계 원칙 SOLID의 이해와 적용

객체 지향 설계 원칙 SOLID는 소프트웨어의 유지보수성, 확장성, 재사용성을 향상시키는 핵심 지침입니다. 이 글에서는 SOLID의 각 원칙을 소개하고, 왜 중요한지, 어떻게 적용할 수 있는지를 탐구

f-lab.kr

참고자료2

 

💠 객체 지향 설계의 5가지 원칙 - S.O.L.I.D

객체 지향 설계의 5원칙 S.O.L.I.D 모든 코드에서 LSP를 지키기에는 어려움. 리스코프 치환 원칙에 따르면 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대신하더라도 의도에 맞게 작동되어

inpa.tistory.com