면접을 봤는데 디자인패턴 관련 질문을 받았다. 한번도 찾아보지 않은 부분이라 정리의 필요성을 느껴 정리를 하려고한다.

  • 솔리드원칙
  • 도메인주도설계
  • 마이크로서비스패턴

위 3가지에 대해 물어봤는데 하나도 몰라서 답을 못했다. 이번장에서는 SOLID원칙을 알아보려고한다.

도메인주도설계
마이크로서비스아키텍처


좋은 객체지향 설계를 위해서는 5가지의 원칙을 꼭 따르는게 좋고 그 5가지 원칙의 앞글자를 따서 SOLID라고 한다.

1. SRP(Single Responsibility Principle) : 단일 책임 원칙

객체는 오직 하나의 책임을 가져야 한다. 즉 객체를 수정할 이유가 오직 하나만 이여야 한다.

사칙연산 함수를 가지고 있는 계산 클래스가 있다고 치자. 이 상태의 계산 클래스는 오직 사칙연산 기능만을 책임진다. 만약 프로그램 수정이 필요할 경우 계산 클래스가 수정될만한 사유는 누가 봐도 사칙연산 함수와 관련 된 문제 뿐이다. 이처럼 단일 책임 원칙은 클래스의 목적을 명확히 함으로써 구조가 난잡해지거나 수정 사항이 불필요하게 넓게 퍼지는 것을 예방하고 기능을 명확히 분리할 수 있게 한다.

만약 하나의 클래스가 두 가지 이상의 책임을 지니게 되면 클래스의 목적이 모호해지고 기능을 수정할 때 영향을 받는 범위도 커져서 유지보수가 힘들어진다.

2. OCP(Open-Closed Principle) : 개방-폐쇄 원칙

객체는 확장에 대해서는 개방적이고 수정에 대해서는 폐쇄적이어야 한다는 원칙이다.

캐릭터 클래스가 있고 캐릭터클래스 내에 이동메서드가 있을 경우 이동이 다를경우 하위클래스에서 이동메서드를 재구현(오버라이딩) 하면 캐릭터클래스는 수정할 필요가 없고(폐쇄적 수정) 이동메서드만 수정하면 된다(개방적 확장).

3. LSP(Liskov Substitusion Principle) 리스코프 치환 법칙

자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이다. 즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다는 것. 상속에 대한 다형성과 관계있다.

이해를 돕기위해 도형을 예시를 들어보자. 도형 클래스와 사각형 클래스가 있고,
사각형 클래스는 도형 클래스의 상속을 받는다고 가정하자.

(1) 도형은 둘레를 가지고 있다.
(2) 도형은 넓이를 가지고 있다.
(3) 도형은 각을 가지고 있다.

일반화 관계(일관성인지 확인하는 방법은 단어를 교체해 보면 알 수 있다.
(1) ~ (3)의 도형이란 단어 대신 사각형을 넣어보자.

(1) 사각형은 둘레를 가지고 있다.
(2) 사각형은 넓이를 가지고 있다.
(3) 사각형은 각을 가지고 있다.

(1) ~ (3) 모두 딱히 이상한 부분이 보이지 않는다.
따라서 도형과 사각형 사이에는 일관성이 있다고 할 수 있다.

여기서 원(Circle) 이라는 도형에 대해 생각해보자.
원 클래스 역시 도형 클래스의 상속을 받는다고 가정하자.
앞에서 언급한 (1) ~ (3)의 도형 단어 대신 원을 대입해보자.

(1) 원은 둘레를 가지고 있다.
(2) 원은 넓이를 가지고 있다.
(3) 원은 각을 가지고 있다.

문장을 읽어보면 (3)번 문장이 어색하다는 것을 알 수 있다.
따라서 도형 클래스는 LSP을 만족하지 않은 설계라 할 수 있다. 따라서 (3)문장에 대해서는 일반화 관계가 성립하도록 수정되어야 한다.
  • 위 예시는 JAVA 객체 지향 디자인 패턴(정인상/채홍석 지음, 한빛미디어, 2014) p.116~117를 참고
4. ISP(Interface Segregation Principle) 인터페이스 분리 원칙

클라이언트에서 사용하지 않는 메서드는 사용해선 안된다. 그러므로 인터페이스를 다시 작게 나누어 만든다. OCP와 비슷한 느낌도 들지만 엄연히 다른 원칙이다. 하지만 ISP를 잘 지키면 OCP도 잘 지키게 될 확률이 비약적으로 증가한다.

예를들면, 우리는 스마트폰으로 전화, 웹서핑, 사진 촬영 등 다양한 기능을 사용할 수 있다. 그런데 전화를 할 때에는 웹서핑, 사진촬영 등 다른 기능은 사용하지 않는다. 따라서 전화기능과 웹서핑 기능 사진 촬영 기능은 각각 독립된 인터페이스로 구현하여, 서로에게 영향을 받지 않도록 설계해야 한다. 이렇게 설계된 소프트웨어는 인터페이스 분리 원칙을 통해 시스템의 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 할 수 있다.

5. DIP(Dependency Inversion Principle) : 의존성 역전 원칙

추상성이 높고 안정적인 고수준의 클래스는 구체적이고 불안정한 저수준의 클래스에 의존해서는 안된다는 원칙으로서, 하위클래스가 상위클래스에 의존을 해야지 상위클래스가 하위클래스에 의존한다는 것은 말도 안되는 소리이다.

chanhee.kim's profile image

chanhee.kim

2019-03-23 16:22

Read more posts by this author