면접 때 많이 받은 질문 중 하나였다. 나 역시 모호하게 느껴져 제대로 대답을 못 했었는데,
이전에 진행했던 객체지향 스터디에서 읽은 책들을 보고 정리해 보았다.
https://github.com/yeonjiyeon/readingstudy
적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력관계를 구축하는 것
→ 객체지향은 실세계 모방이라기보다는 실세계 은유라 할 수 있다.
→ 협력은 객체지향 설계의 품질을 결정하는 가장 중요한 요소
객체의 책임은 ‘객체가 무엇을 알고 있는가’와 ‘무엇을 할 수 있는가’로 구성된다.
→ 객체는 다른 객체가 ‘무엇(What)’ 을 수행하는지 알 수 있지만 ‘어떻게(how)’ 수행하는지에 대해서는 알 수 없다.
-객체지향에서의 캡슐화 예시 : 접근제어자, getter, setter
: 상위 클래스의 특성을 하위 클래스에서 상속(특성 상속)하고 거기에 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미다.
상위 클래스 - 하위 클래스(슈퍼 클래스 - 서브클래스)
상위 클래스쪽으로 갈수록 추상화, 일반화됐다고 말하고,
하위 클래스 쪽으로 갈수록 구체화, 특수화됐다고 말한다.
하위 클래스는 상위 클래스다.
*상속은 is a 관계를 만족해야 한다?
하위 클래스 is a 상위 클래스
하위 클래스 is a kind of 상위 클래스
→ 공통점을 기반으로 객체들을 묶기 위함
⇒ 추상화: 구체적인 것을 분해해서 관심 영역(Application Boundary)에 있는 특성만 가지고 재조합 하는 것 = 모델링
오버라이딩? 오버로딩?
-오버라이딩(Overriding) : 같은 메서드이름, 같은 인자 목록으로 상위 클래스의 메서드를 재정의
-오버로딩(Overloading) : 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복 정의
객체지향으로 설계할 수 있도록 도와주는 원칙들이다. 하지만 이 원칙이 반드시 정답은 아니다.
고려는 하되, 정답이 아님을 기억하자!
"어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다."
-클래스 뿐만 아닌 속성, 메서드, 페키지, 모듈, 컴포넌트, 프레임워크 등에도 적용할 수 있는 개념이다.
→변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것
-추상화와 가장 연관 깊은 원칙이다. —> 책임의 범위를 적절하게 잘 조절하는게 중요!!!
"자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다."
예) JDBC, JVM
→ 개방 폐쇄 원칙을 무시하고 프로그램을 작성하면 객체 지향 프로그래밍의 가장 큰 장점인 유연성, 재사용성, 유지보수성 등을 얻을 수 없다.
"서브 타입은 언제나 자신의 기반 타입(base type)으로 교체할 수 있어야한다."
→ 리스코프 치환 원칙은 객체 지향의 상속이라는 특성을 올바르게 활용하면 자연스럽게 얻게 되는 것이다.
"클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안 된다."
→ 단일 책임 원칙과 인터페이스 분할 원칙은 같은 문제에 대한 두 가지 다른 해결책
→ 특별한 경우가 아니라면 단일 책임 원칙을 적용하는 것이 더 좋은 해결책이라고 할 수 있다.
*인터페이스 최소주의 원칙 : 인터페이스를 통해 메서드를 외부에 제공할 때 최소한의 메서드만 제공하라는 것
"고차원 모듈은 저차원 모듈에 의존하면 안 된다. 두 모듈 모두 다른 추상화된 것에 의존해야 한다."
"추상화된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것이 추상화된 것에 의존해야 한다."
"자주 변경되는 구체화된 클래스에 의존하면 안된다."
:자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 것
*BUT객체지향은 중요한 개념이지만 항상 옮은 것은 아니다!(모든 것에 다 통용되는 완벽한 프로그래밍 방법은 없다. 모두 장단점이 있다.)
절차 지향 프로그래밍, 데이터 지향 프로그래밍, 함수형 프로그래밍 등 프로젝트 성격에 맞는 것을 쓰는 것이 좋다!
참고 자료
-숫자야구 라이브 코딩(두두님)
-객체지향의 사실과 오해(조영호님)
-스프링의 핵심원리(김영한님)
-스프링 입문을 위한 자바 객체 지향의 원리와 이해(김종민님)