객체지향 개념은 1970년대에 출현
이전에는 절차지향, 하지만 점점 프로그래밍의 복잡도가 증가하면서 유지보수, 개발기간 등의 부분에서 문제가 발행함, 이를 해결하기 위해 효과적인 개발방식을 선택하게 되었고, 객체지향(추상화, 상속, 은닉, 재사용, 인터페이스 등)으로 진화!!
현실에 존재하는 사물을 그대로 모델링하여, 이들의 행위와 속성을 정의, 절차가 아닌 객체가 중심이 되어 실제 사물이 동작하는 방식으로 설계, 사물에 대해서는 객체(Object)라고 부르며, 해당 사물이 하는 행위(Method)로 정의하고 해당 사물이 가지는 속성을 변수(Variable)라고 정의
Java는 1995년 썬마이크로시스템즈의 작은 언어를 지향하는 언어로 소개됨
당시에 C++과 유사한 언어의 구문을 채택하였으나, C++의 시스템 레벨 접근, 메모리 직접 할당 및 해제, 포인터 등 복잡한 개발 방식을 사용하지는 않음
[객체의 3가지 요소]
- 상태 유지 : 상태 정보를 저장하고 유지되어야 하며, 이런 속성(variable)은 변수로 정의되어야 한다.
- 기능 제공 : 기능(method)를 제공해야 한다. 외부에서 객체에 직접 접근하지 않고 메소드를 통해 속성에 접근하여 변경하는 방식이어야 한다
- 고유 식별자 제공 (객체의 유일성) : 각 개체는 고유한 식별자를 가져야 한다.
[물리객체와 개념객체]
- 물리객체는 말 그대로 실제로 존재하는 사물을 의미
- 개념객체는 웹 시스템에서 서비스(Service)에 해당, 비즈니스 로직 처리를 담당하는 부분을 의미
[객체지향의 4대 특성]
1. 캡슐화
- 객체의 속성을 보호, 외부에서 속성에 직접 접근이 아니라 객체의 메소드를 통해 속성을 변경
- Getter / Setter, CRUD, Business Logic, 객체의 생명 주기 처리(destroy(), disconnect(), quit() 등)
- 추상화를 제공, 재사용성 향상, 유지보수 용이, 무결성(public method는 입력된 매개변수를 validation 한 후 실행)
2. 상속
- 하위로 내려갈수록 구체화
- 프로그램 구조에 대한 이해가 용이, 재사용성 : 슈퍼 클래스의 기능을 그대로 사용가능
- 확장성 향상, 유지보수 향상
3. 다형성
- 하나의 개체가 여러 형태로 변화하는 것이 가능
- 오버라이딩 : 같은 메소드지만 동작하는 방식이 전혀 다를 수 있음
4. 추상화
- 객체지향에서 추상화는 모델링을 의미
- 구체적으로 공통적인 부분, 또는 특정 특성을 분리해서 재조합 하는 부분이 추상화
[객체지향 설계 5원칙 - SOLID]
- 좋은 소프트웨어 설계에서는 결합도(coupling)는 낮추고 응집도(cohesion)는 높여야 한다
1. SRP(Single Responsibility Principle - 단일 책임 원칙)
- 정의 : 하나의 클래스는 하나의 기능만을 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임을 수행하는 데 집중되어 있어야 한다.
- 책임 영역이 확실해지고 책임을 적절히 분배함으로써 코드의 가독성 향상, 유지보수 용이라는 이점을 볼 수 있음
2. OCP(Open Close Principle - 개방폐쇄의 원칙)
- 정의 : 소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는 확장에는 열려있고, 변경에는 닫혀있어야 한다.
- 변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 가능한 극대화 해야 한다는 의미
- 요구사항의 변경이나 추가사항이 발생하더라도, 기존 구성요소는 수정이 일어나지 말아야 하며, 기존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한다는 뜻
- OCP를 가능케 하는 중요 메커니즘은 추상화와 다형성
- 적용 방법 : 변경될 것과 변하지 않을 것을 엄격히 구분 > 이 두 모듈이 만나는 지점에 인터페이스를 정의 > 구현에 의존하기보다 정의한 인터페이스에 의존하도록 코드 작성
ex) JDBC Interface
3. LSP(The Liskov Substitution Principle - 리스코브 치환의 원칙)
- 정의 : 서브 타입은 언제나 기반 타입으로 교체할 수 있어야 한다. 즉 서브 타입은 언제나 기반 타입과 호환될 수 있어야 한다.
- 서브타입은 기반타입이 약속한 규약을 지켜야 한다.
ex) LinkedList를 parameter로 받는 부분을 Collection으로 변경 >> Collection Framework의 다른 자료구조도 parameter로 사용할 수 있다
4. ISP(Interface Segregation Principle - 인터페이스 분리의 원칙)
- 정의 : 클라이언트가 사용하지 않는 메소드에 의존하지 않아야 한다. 즉, 한 클래스는 자신이 사용하지 않는 메소드는 구현하지 말아야 한다.
- 다른 정의 : 하나의 통합된 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다
ex) JTable은 자신을 이용하여 테이블을 만드는 객체, 즉 모든 서비스를 필요로 하는 객체에게는 기능 전부를 노출하지만, 이벤트 처리와 관련해서는 여러 Listener 인터페이스를 통해 해당 기능만 노출한다
5. DIP(Dependency Inversion Principle - 의존성 역전의 원칙)
- 정의 : high-level 모듈은 low-level 모듈의 구현에 의존해서는 안 된다. low-level 모듈이 high-level 모듈에서 정의한 추상 타입에 의존해야 한다.
- 구조적 디자인에서 발생하던 하위레벨 모듈의 변경이 상위레벨 모듈의 변경을 요구하는 위계관계를 끊는 의미의 역전
- 추상을 매개로 메시지를 주고 받음으로써 관계를 최대한 느슨하게 만드는 원칙
- DIP의 키워드는 ‘IoC’, ‘Hook 메소드’, ‘확장성’
※ Hook method : 슈퍼클래스에서 디폴트 기능을 정의해두거나 비워뒀다가 서브클래스에서 선택적으로 오버라이드 할 수 있도록 만들어 둔 메소드를 훅 메소드라 함
[POJO]
- EJB로부터 탈출하자
- 특정 외부 라이브러리에 종속되지 않고 순수 자바로 개발하자
- 특정 환경에 종속되지 않게 개발하자
[Reference]
- 패스트캠퍼스, "한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online - 스프링 입문"
- nextree, "객체지향 개발 5대원리: SOLID", http://www.nextree.co.kr/p6960/
- 머루의개발블로그, "의존 역전 원칙", http://wonwoo.ml/index.php/post/1717
- 머루의개발블로그, "인터페이스의 분리", http://wonwoo.ml/index.php/post/1675