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

코드싸개 김 씨·2024년 12월 21일
0

객체 지향 5원칙?

객체 지향? 절차 지향 안 따르고 객체 만드는거 ㅋㅋ

내가 객체 지향에 대한 이론을 제대로 알기 전까지의 생각이었다.

뭐 사실..틀린 마인드?는 아닌거 같긴한데

제대로 알기 전까지는 별 생각 없이 개발을 했던 것 같다.

그래서 다시금 복기해볼 겸 이 글을 적는다.

SOLID?

SOLID는 5원칙의 앞 글자들을 따서 만들어진 단어인데, 5원칙은 아래와 같다.

  • SRP(Single responsibility princlple): 단일 책임 원칙
  • OCP(Open/Closed priciple): 개방-폐쇄 원칙
  • LSP(Liskov subsitution principle): 리스코프 치환 원칙
  • ISP(Interface segregation principle): 인터페이스 분리 원칙
  • DIP(Dependency inversion principle): 의존관계 역전 원칙

보통 그냥 다 앞글자 따서 XXP 이렇게 만들어진 원칙들이다. (하츄핑)

위에서부터 찬찬히 알아보자!

1. SRP / 단일 책임 원칙

단일 책임 원칙은 말 그대로다. 하나의 객체, 즉 클래스가 하나의 책임만 가져야 한다는 것이다.

이때 중요한 기준은 코드의 변경이다.
➡️ Ex: 코드를 바꿨을 때, 전체적인 파급이 적은가?

이 원칙은 사실 완벽하게 지켜지기는 쉽지 않은 듯하다.

한 클래스의 책임을 너무 작게, 너무 크게 해도 법칙을 위반하기 때문이다.

그렇기에, 이 클래스들의 역할을 적절하게 조절, 분배하는 것이 객체지향의 묘미라고 할 수 있다고 한다!

2. OCP / 개방 - 폐쇄 원칙

확장에는 열려있지만, 변경에는 닫혀있어야 한다?

개방 폐쇄 원칙의 핵심이다. 사실 위 문장 하나만으로는 조금 이해하기 모호하다.

사실 이건 객체지향의 3요소 중 하나인 다형성과 관련이 있는데,

핵심적인 기능은 최대한 변하지 않되, 새로운 기능의 확장은 쉽도록 설계해야 한다는 원칙 같다.

정말 좋은 원칙이다..좋은 원칙인데, 이 객체 지향 5원칙에서의 모순되는 문제가 하나 생기는데, 아래에서 설명하도록 하겠다.

3. LSP / 리스코프 치환 원칙

간단하게 설명하자면, 다음과 같다.

인터페이스가 있으면, 그 인터페이스의 규약을 맞추어야 한다.

이것은 프로그램의 정확성과 연관되어 있다고 볼 수 있다.

당연히 인터페이스가 만들어진 의도와 다르게 구현되어도 컴파일이 되지만, 그렇게 구현된 인터페이스는 의미가 없지 않을까?

➡️ 인터페이스의 의도에 맞게 구현하는 것이 중요하다는 원칙이라고 할 수 있겠다.

4. ISP / 인터페이스 분리 원칙

특정 클라이언트를 위한 인터페이스 여러개가, 범용 인터페이스 하나보다 낫다.

인터페이스 구성을 모호하게 하지말고, 구체적으로 만들라는 원칙 같다.

EX: 자동차 인터페이스-> 운전 인터페이스, 정비 인터페이스
사용자 -> 운전자 클라이언트와 정비사 클라이언트

이런 식으로 분리했을 때, 어느 한 쪽의 인터페이스가 변해도, 다른 쪽 인터페이스에 영향을 미치지 않는다.

즉, 인터페이스가 명확해지고 이를 대체하는 것도 쉬워진다.

5. DIP / 의존 관계 역전 원칙

추상화에 의존해야지, 구체화에 의존하면 안 된다.

개인적으로 가장 와닿은 원칙이었다. 별 생각 없이 개발하던 나에게는 좀 큰 충격으로 다가왔는데, 각설하고 설명하겠다.

그니까 역할에 의존해야지, 구현에 의존하면 안 된다는 원칙인데..

이러게 되면, 순수 자바에서는 위에서 언급했던 OCP / 개방 - 폐쇄 원칙과 모순되게 된다!

예를 들자면, TestService라는 인터페이스가 있다면, 이 TestService는 이 인터페이스를 구현한 TestServiceImpl이라는 구현 클래스로 선언될 수 있는데


public class ExServiceImpl implements ExService{
	// 인터페이스가 구체화된 클래스를 고르게 되는 상황
	TestService testService = new TestServiceImpl();
}

이렇게 되면 사실 구현체와 추상, 둘 다에 의존하는 상황이 되게 된다.

사실 그래서 우리가 JAVA 프레임워크로 스프링을 쓰는 이유기도 하다.

(근데 스프링을 설명하려는 글은 아니니까 대충 여기서 마무리하려 한다.)

결론

사실 아직도 내가 이 원칙을 잘 지키며 개발하고 있는지는 모르겠다.

하지만 이전보다는 내가 '잘 지키고 있나?' 라고 의식하며 코드를 작성하게 된 시점에서 무지한 상태였던 나보다는 훨씬 발전했다고 생각한다.

뭔가 되게 투박하고 조잡하게 설명을 하게된 느낌이지만,

정말 혹시라도 이 영양가 없는 글을 읽어주신 분이 있다면

정말 감사합니다!

좋은 하루 되세요!!👍👍

profile
인생 망하기 전에 시작합니다

0개의 댓글