섹션 1. 객체 지향 설계와 스프링
객체 지향 특징
객체 지향 프로그래밍 : 컴퓨터 프로그램을 객체들의 모임으로 파악하고자 하는 것.
프로그램을 유연하고 변경 용이하게 만듬(컴포넌트를 쉽고 유연하게 변경하면서 개발)
→ 대규모 sw 개발에 사용
자바의 다형성 활용
- 역할 : 인터페이스
- 구현 : 인터페이스를 구현한 클래스, 구현 객체
→ 일반 상속 관계도 다형성이 가능하지만 가급적이면 다중 구현 가능한 인터페이스로
객체 설계 시 역할을 먼저 부여 → 역할을 수행하는 구현 객체 만들기
인터페이스 자체가 바뀌면 클라이언트와 서버 모두에 변경이 발생한다.
→ 인터페이스를 안정적으로 변화가 안생기게끔 잘 설계하는 것이 중요!
스프링과 객체 지향
- 다형성이 중요
- 스프링은 다형성을 극대화시켜줌
- 스프링에서 IoC, DI은 다형성을 활용하여 역할과 구현을 편리하게 다룰 수 있도록 지원
SOLID : 좋은 객체 지향 설계의 5가지 원칙
- SRP (Single responsibility principle) 단일 책임 원칙
: 하나의 클래스는 하나의 책임만 가져야 한다.
→ 하나의 책임은 모호하다. 따라서 중요한 기준은 ‘변경’이며, 변경이 있을 때 파급 효과가 적으면 SRP를 잘 따른 것
- *OCP (Open/Closed principle) 개방-폐쇄 원칙
: 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
→ 그러나 구현 객체 변경 시 클라이언트 코드도 변경해야 한다.
다형성을 사용했지만 OCP 원칙을 지킬 수 없다?
→ 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요 : 스프링 컨테이너
- LSP (Liskov substitution principle) 리스코프 치환 원칙
: 프로그램 객체는 프로그램의 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
→ 단순 컴파일 성공을 이야기하는 것이 아님.
- ISP (Interface segregation principle) 인터페이스 분리 원칙
: 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다.
→ 자동차 인터페이스 : 운전 / 정비, 사용자 클라이언트 : 운전자, 정비사
인터페이스가 명확해지고 대체 가능성이 높아진다.
- *DIP (Dependency inversion principle) 의존관계 역전 원칙
: 프로그래머는 추상화에 의존해야지 구체화에 의존하면 안된다.
→ 구현 클래스에 의존하지 말고 역할(인터페이스)에 의존하라는 의미로, 클라이언트가 구현체에 의존하게 되면 변경이 어려워진다. 따라서 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다.
객체 지향의 핵심은 ‘다형성’
- 다형성 만으로는 구현 객체 변경시 클라이언트 코드도 함께 변경
- 다형성 만으로는 OCP, DIP를 지킬 수 없음
스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원
- DI : 의존관계, 의존성 주입
- DI 컨테이너 제공
→ 클라이언트 코드의 변경 없이 기능 확장 가능(부품교체하듯 쉽게 개발 가능)
모든 설계에 역할과 구현을 분리
애플리케이션 설계도 공연을 설계하듯 배역(인터페이스)만 만들어두고 배우(구현체)는 언제든 유연하게 변경할 수 있도록 만드는 것 ⇒ 좋은 객체 지향 설계
이상적으로는 모든 설계에 인터페이스 부여하기
→ 실무에서는 추상화라는 비용이 발생. 확장 가능성이 있는 경우에만 인터페이스를 도입하는 것도 하나의 방법.