좋은 객체지향 설계를 위해서는 다음의 5가지 원칙을 따르는 것이 좋고, 다음의 원칙들을 기반으로 디자인 패턴이 되기 때문에, 디자인 패턴을 공부하기 전에 알아두면 왜 그 패턴이 좋은 패턴인지에 대해서 좀 더 깊게 이해할 수 있다.
이 객체지향 5가지의 원칙, 앞글자를 따서 (SOLID)라고도 한다.
S - SRP(Single responsibility principle) 단일 책임 원칙
- 모든 클래스는 단 하나의 책임을 가진다. 다시 말하면 클래스를 수정할 이유가 오직 하나여야한다는 뜻이기도 하다.
- 예를 들어, 계산기 클래스가 있을때, 계산을 하는 책임과 GUI를 나타낸다는 책임은 서로 분리되어야 한다. 계산기 클래스에 GUI를 나타내는 부분까지 있을경우, 이는 SRP를 위반한다.
O - OCP(Open Closed Principle) 개방 - 폐쇄 원칙
-
확장에 대해서는 개방 되어 있어야 하지만, 수정에 대해서는 폐쇄 되어야 한다.
-
예를 들어, 캐릭터를 하나 생성한다고 할때, 각각의 캐릭터가 움직임이 다를 경우 움직임의 패턴 구현을 하위 클래스에 맡긴다면 캐릭터 클래스의 수정은 필요가없고(수정에 대해 폐쇄) 움직임의 패턴만 재정의 하면 된다.(확장에 대해 개방)
L - LSP(Liskov Substitusion Principle) 리스코프 치환 법칙
이 링크를 참고하면 더 자세히 알 수 있다.
자식 클래스는 언제나 자신의 부모클래스를 교체할 수 있다는 원칙이다. 즉 부모클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다는것.
즉, 업캐스팅을 해도 아무런 문제가 안되어야 한다는 것이다. Student의 부모 클래스가 Person이라고 했을때,
Student s = new Student();
Person p = (Person)s;
라고 해도 문제가 안되어야한다는 뜻.
쉽게 설명되어 있는 부분이 있어서 추가한다.
이해를 돕기위해 도형을 예시를 들어보자. 도형 클래스와 사각형 클래스가 있고, 사각형 클래스는 도형 클래스의 상속을 받는다고 가정하자.
(1) 도형은 둘레를 가지고 있다.
(2) 도형은 넓이를 가지고 있다.
(3) 도형은 각을 가지고 있다.
일반화 관계(일관성인지 확인하는 방법은 단어를 교체해 보면 알 수 있다. (1) ~ (3)의 도형이란 단어 대신 사각형을 넣어보자.
(1) 사각형은 둘레를 가지고 있다.
(2) 사각형은 넓이를 가지고 있다.
(3) 사각형은 각을 가지고 있다.
(1) ~ (3) 모두 딱히 이상한 부분이 보이지 않는다. 따라서 도형과 사각형 사이에는 일관성이 있다고 할 수 있다.
여기서 원(Circle) 이라는 도형에 대해 생각해보자. 원 클래스 역시 도형 클래스의 상속을 받는다고 가정하자. 앞에서 언급한 (1) ~ (3)의 도형 단어 대신 원을 대입해보자.
(1) 원은 둘레를 가지고 있다.
(2) 원은 넓이를 가지고 있다.
(3) 원은 각을 가지고 있다.
문장을 읽어보면 (3)번 문장이 어색하다는 것을 알 수 있다. 따라서 도형 클래스는 LSP을 만족하지 않은 설계라 할 수 있다. 따라서 (3)문장에 대해서는 일반화 관계가 성립하도록 수정되어야 한다.
I - ISP(Interface Segregation Principle) 인터페이스 분리 원칙
- 클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙.
- 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다.
- 이는 다시 말해서, 자신이 사용하지 않는 기능(인터페이스)에는 영향을 받지 말아야 한다는 의미이다.
- 한가지 예를 들어보자. 우리는 스마트폰으로 전화, 웹서핑, 사진 촬영 등 다양한 기능을 사용할 수 있다. 그런데 전화를 할 때에는 웹서핑, 사진촬영 등 다른 기능은 사용하지 않는다. 따라서 전화기능과 웹서핑 기능 사진 촬영 기능은 각각 독립된 인터페이스로 구현하여, 서로에게 영향을 받지 않도록 설계해야 한다. 이렇게 설계된 소프트웨어는 인터페이스 분리 원칙을 통해 시스템의 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 할 수 있다.
- 일반적인 클래스를 하나 구현해서 사용하지도 않는 함수를 implement시키지 말고, 여러개의 구체적인 클래스를 생성 해 implement시키면 깔끔한 구조가 된다.->일반적으로 여러개의 클래스를 implement하는 구조가 될 경우가 큼
D - DIP(Dependency Inversion Principle) 의존성 역전 법칙
- 상위클래스는 하위클래스에 의존해서는 안된다는 법칙. 하위클래스가 상위클래스에 의존을 해야지 상위클래스가 하위클래스에 의존한다는 것은 말도안되는 소리이다.