개발 상식

SOLID 원칙

컴공누누 2023. 11. 19. 14:38

SOLID 원칙

SOLID 원칙이란 객체 지향 설계에서 지켜줘야 할 5개의 소프트웨어 개발 원칙을 말하며 5개의 원칙의 앞글자를 따서 SOLID라고 부른다. 각각 SRP, OCP, LSP, ISP, DIP를 말한다.

SPR (Single Responsibility Principle) 단일 책임 원칙

  • 단일 책임 원칙이란 모든 클래스는 하나의 책임만 가져야 한다는 원칙을 말한다.

  • 여기서 책임은 기능으로 해석할 수 있고 하나의 클래스가 여러 기능을 담당하게 되면 수정을 해야 할 상황이 발생하면 복잡한 상황이 발생할 수 있다.

  • 하지만 하나의 기능만 담당한다면 수정할 상황이 생기더라도 그 클래스만 수정하면 되기 때문에 프로그램의 유지보수성을 높일 수 있다.

class Chef() {
    fun cook() { println("요리하기") }
    fun plate() { println("플레이팅 하기") }
    fun serving() { println("서빙하기") }
    fun calculate() { println("계산하기") }
}

위의 코드를 보면 Chef 클래스에서 요리, 플레이팅 외에도 서빙과 계산을 담당하고 있다. 하지만 여기서 Watiter 클래스를 추가하면 웨이터의 기능을 추가하더라도 Chef 클래스에서는 변화를 없앨 수 있다.

변경된 코드

class Chef() {
    fun cook() { println("요리하기") }
    fun plate() { println("플레이팅 하기") }
}

class Waiter() {
    fun serving() { println("서빙하기") }
    fun calculate() { println("계산하기") }
}

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

  • 개방 폐쇄의 원칙은 클래스는 확장에는 열려있어야 하며 수정에는 닫혀있어야 한다는 것을 말한다.

  • 쉽게 설명하면 추상 클래스와 상속을 사용하여 클래스 설계를 하는 것을 말한다.

interface Car {
    fun accel()
    fun brake()
}

class SportsCar() : Car {
    override fun accel() {
        println("속도 10 증가")
    }

    override fun brake() {
        println("속도 5 감소")
    }
}

class Bus() : Car {
    override fun accel() {
        println("속도 5 증가")
    }

    override fun brake() {
        println("속도 3 감소")
    }
}
  • 운전자는 자동차를 변경하더라도 똑같이 엑셀을 밟고 브레이크를 밟을 수 있다. 이를 통해 운전자는 변경에는 닫혀 있다는 것을 알 수 있다.

  • 하지만 자동차는 SportCar, Bus 클래스 이외에도 인터페이스를 통해 다른 자동차 클래스를 확장할 수 있다. 이를 통해 확장에는 열려 있다는 것을 알 수 있다.

LCP (Liskov Substitution Principle) 리스코프 치환 원칙

리스코프 치환 원칙은 자식 타입은 언제든 부모 타입으로 교체할 수 있어야 한다는 원칙이다.

open class Car(
    open var speed : Int
) {
    open fun accel() {
        speed += 10
    }
}

class Bus(
    override var speed: Int,
    private var distance: Int
) : Car(speed) {
    override fun accel() {
        speed += 10
        distance += 1
    }
}
  • 부모 클래스인 Car 클래스가 제공하는 accel 함수를 자식 클래스인 Bus 클래스에서도 수행을 하고 있는 것을 보면서 원칙을 지킨 것을 볼 수 있다.

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

  • 인터페이스 분리 원칙이란 클라이언트가 자신이 이용하지 않는 메서드를 의존하지 않아야 한다는 원칙이다.

  • 쉽게 설명하면 앞에 SRP 원칙에서 Chef 클래스와 Waiter 클래스로 분리하였는데 그 이유는 Chef 클래스에서 담당하지 않는 기능들이기 때문에 그 기능을 담당하는 Waiter 클래스로 옮겨 준 것이다.

interface Chef() {
    fun cook() { println("요리하기") }
    fun plate() { println("플레이팅 하기") }
}

interface Waiter() {
    fun serving() { println("서빙하기") }
    fun calculate() { println("계산하기") }
}

DIP (Dependancy Inversion Principle) 의존 관계 역전 원칙

  • 의존 관계 역전 원칙은 구현 클래스에 의존하지 않고 추상 클래스에 의존하는 것을 뜻한다.

  • 의존을 할 때 변화가 잦은 것보다는 변화가 없는 즉 추상 클래스에 의존하라는 것을 말한다.

DIP

면접 예상 질문

1. SOLID 원칙에 대해 설명해주세요.

2. 클래스는 확장에는 열려있어야 하며 수정에는 닫혀있어야 한다는 원칙은 무엇인가요?

참고 URL

'개발 상식' 카테고리의 다른 글

RESTful API란?  (0) 2023.12.08
객체 지향 프로그래밍  (0) 2023.11.17