SOLID 원칙

SungminPark·2024년 3월 3일

공부

목록 보기
3/3
post-thumbnail

객체지향 프로그래밍의 5가지 설계 원칙, SOLID


SOLID란 객체 지향 프로그래밍을 하면서 지켜야하는 5대 원칙으로 각각

  • SRP(단일 책임 원칙),
  • OCP(개방-폐쇄 원칙),
  • LSP(리스코프 치환 원칙),
  • DIP(의존 역전 원칙),
  • ISP(인터페이스 분리 원칙)

의 앞글자를 따서 만들어졌다.

SOLID 원칙을 철저히 지키면 시간이 지나도 변경이 용이하고, 유지보수와 확장이 쉬운 소프트웨어를 개발하는데 도움이 되는 것으로 알려져있다.

단일 책임의 원칙(SRP, Single Responsibility Princip


SRP는 하나의 모듈이 하나의 책임을 가져야 한다.

→ 모듈이 변경되는 이유가 한가지여야 함으로 받아들여야 한다.

: 해당 모듈이 여러 대상 또는 액터들에 대해 책임을 가져서는 안되고, 오직 하나의 액터에 대해서만 책임을 져야 한다.

모듈은 클래스 혹은 클래스의 모음 등으로 해석할 수 있다

단일 책임 원칙을 제대로 지키면 변경이 필요할 때 수정할 대상이 명확해진다. 그리고 이러한 단일 책임 원칙의 장점은 시스템이 커질수록 극대화된다.

하지만, SRP를 위반하는지 판단하는것은 상당히 어렵다.

그 이유는 동일한 대상이라 할 지라도 유스케이스나 요구 사항의 단계에 따라 책임이 단일한지 여부가 달라질 수 있기 때문이다.

유스케이스를 변경하거나 요구 사항이 달라질 경우에는 기존에 충족했던 단일 책임 원칙이 충족되지 못할 수 있다. 또한 해당 클래스를 어떻게 바라보는가에 따라서도 다를 수 있다.

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


OCP는 확장에 대해 열려있고 수정에 대해서는 닫혀있어야 한다는 원칙이다.

  • 확장에 대해 열려 있다 : 요구사항이 변경될 때 새로운 동작을 추가하여 애플리케이션의 기능을 확장할 수 있다.
  • 수정에 대해 닫혀 있다 : 기존의 코드를 수정하지 않고 애플리케이션의 동작을 추가하거나 변경할 수 있다.
💡 상속을 잘 써야한다.

OCP의 원칙을 지키기 위해서는 추상화에 의존해야한다. 추상화란 핵심적인 부분만 남기고, 불필요한 부분은 제거함으로써 복잡한 것을 간단히 하는 것이고, 추상화를 통해 변하지 않는 부분만 남김으로써 기능을 구체화하고 확장할 수 있다.

OCP가 본질적으로 얘기하는 것은 추상화이며, 이는 결국 런타임 의존성과 컴파일타임 의존성에 대한 이야기이다. 여기서 런타임 의존성이란 애플리케이션 실행 시점에서의 객체들의 관계를 의미하고, 컴파일타임 의존성이란 코드에 표현된 클래스들의 관계를 의미한다.

인터페이스 분리 원칙 (Interface segregation principle, ISP)


💡 캡슐화

객체가 충분히 높은 응집도의 작은 단위로 설계됐더라도, 목적과 관심이 각기 다른 클라이언트가 있다면 인터페이스를 통해 적절하게 분리해줄 필요가 있는데, 이를 인터페이스 분리 원칙이라고 부른다.

즉, 인터페이스 분리 원칙이란 클라이언트의 목적과 용도에 적합한 인터페이스 만을 제공하는 것이다.

인터페이스 분리 원칙을 준수함으로써 모든 클라이언트가 자신의 관심에 맞는 퍼블릭 인터페이스(외부에서 접근 가능한 메세지)만을 접근하여 불필요한 간섭을 최소화할 수 있으며, 기존 클라이언트에 영향을 주지 않은 채로 유연하게 객체의 기능을 확장하거나 수정할 수 있다.

클라이언트에 따라 인터페이스를 분리하면 변경에 대한 영향을 더욱 세밀하게 제어할 수 있다.

그리고 이렇게 인터페이스를 클라이언트의 기대에 따라 분리하여 변경에 의해 의한 영향을 제어하는 것을 인터페이스 분리 원칙이라고 부른다.

여기서 인터페이스는 꼭 하나의 인터페이스 파일에만 해당하지는 않는다. 인터페이스 분리 원칙에서 이야기하는 인터페이스는 넓게 보아 아래의 내용들 까지 확장될 수도 있다.

  • API나 기능의 집합
  • 단일 API 또는 기능
  • 객체 지향 프로그래밍의 인터페이스

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


💡 다형성을 잘 써야한다

리스코프 치환 원칙이란 하위 타입은 상위 타입을 대체할 수 있어야 한다는 것이다.

즉, 해당 객체를 사용하는 클라이언트는 상위 타입이 하위 타입으로 변경되어도, 차이점을 인식하지 못한 채 상위 타입의 퍼블릭 인터페이스를 통해 서브 클래스를 사용할 수 있어야 한다는 것이다.

리스코프 치환 원칙은 자식 클래스가 부모 클래스를 대체하기 위해서는 부모 클래스에 대한 클라이언트의 가정을 준수해야 한다는 것을 강조한다.

리스코프 치환 원칙을 위반할 수 있는 상황들

  • 하위 클래스가 상위 클래스에서 선언한 기능을 위반하는 경우
    • 상위 클래스가 정의한 함수를 하위 클래스에서 다른 기준으로 변경한 경우
  • 하위 클래스가 입력, 출력 밎 예외에 대한 상위 클래스의 계약을 위반하는 경우
    • 상위 클래스의 예외 처리를 하위클래스에서 변경하는 경우
  • 하위 클래스가 상위 클래스의 주석에 나열된 특별 지침을 위반하는 경우
    • 상위클래스의 메서드에 나열된 특별 지침을 하위 클래스에서 지키지 않는 경우

의존 역전 원칙 (Dependency Inversion Principle, DIP)


💡 의존성 역전 → 의존성 주입을 표현한다.

의존 역전 원칙이란 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 되며, 저수준 모듈이 고수준 모듈에 의존해야 한다는 것이다.

객체 지향 프로그래밍에서는 객체들 사이에 메세지를 주고 받기 위해 의존성이 생기는데, 의존성 역전의 원칙은 올바른 의존 관계를 위한 원칙에 해당된다.

여기서 각각 고수준 모듈과 저수준 모듈이란 다음을 의미한다.

  • 고수준 모듈 : 입력과 출력으로부터 먼 추상화된 모듈
  • 저수준 모듈 : 입력과 출력으로부터 가까운 구현 모듈

의존 역전 원칙이란 결국 비즈니스와 관련된 부분이 세부 사항에는 의존하지 않는 설계 원칙을 의미한다.

profile
개발자 준비 중 입니다

0개의 댓글