객체 지향 프로그래밍 (Object Oriented Programming a.k.a OOP)
사물, 생물, 개념 등을 객체로 바라보고 이를 객체들의 유기적 모임으로 파악
각각의 객체는 메시지를 통해 데이터를 주고 받으며 처리
프로그램을 유연하고 변경하기 쉽게 설계 -> 대규모 프로젝트에서 많이 채택
객체 지향의 특징
캡슐화 (Encapsulation) : 외부에서 필요하지 않은 부분은 숨기는 특징
상속 (Extend) : 객체들은 부모와 같은 자식 관계를 가질 수 있다. -> 중복 제거
추상화 (Abstract) : 객체의 주요한 특징만을 남기고 공통된 특징을 뽑아내는 것
다형성 (Polymorphism) : 같은 타입이라면 여러 형태를 가질 수 있는 특징
주로 인터페이스를 통해 구현 (오버라이딩, 오버로딩도 가능)
"나는 차를 가지고 있다" -> "차" 는 포르쉐, 페라리 등 교체 가능
운전자 (클라이언트) 는 차가 어떻게 설계되었는지 알 필요 없음
운전자는 차의 기능과 종류가 바뀌더라도 운전 방법만 알고 있으면 됨
Why? 차를 만들 때 모두가 같은 인터페이스를 사용하기 때문
-> 객체지향적으로 설계할 때는 역할과 구현을 명확히 구분해야함
- 역할을 인터페이스로 작성하고 상세한 부분은 클래스로 구현
다형성의 본질은 클라이언트의 코드를 변경하지 않아도 구현기능을 유연하게
변경할 수 있다는 것
SOLID 원칙
SRP : 단일 책임 원칙
한 클래스는 하나의 책임만 가져야 함
기준 = 변경
- 변경 시 파급효과가 적거나 없다면 SRP 를 준수한 설계
OCP : 개방 - 폐쇄 원칙
확장에는 열려있고 변경에는 폐쇄적이어야 함
다형성에서 얘기했듯이 운전자는 바뀌지 않고 자동차만 추가하여 변경
- 이런 경우도 OCP 를 완전히 지킬 수는 없음
- 이러한 문제를 해결하기 위해 외부에서 객체를 생성하고 연관관계를 맺어줌
- LSP : 리스코프 치환 법칙
- 객체는 프로그램의 정확성을 깨트리지 않으면서 하위 타입을 변경할 수 있어야 함
- 즉, 하위 타입은 인터페이스에서 설계한 원칙을 반드시 지켜야 함
- 악셀 기능을 앞으로 가도록 설계 했다면 이를 구현한 구현체 (아반떼) 도
앞으로 가도록 기능을 구현해야 함
- ISP : 인터페이스 분리 법칙
- 특정 클라이언트를 위한 인터페이스를 한 개보다 여러 개로 설계하는 것이 좋음
- 자동차 인터페이스 - > 운전 인터페이스, 정비 인터페이스로 분리
DIP : 의존관계 역전 법칙
프로그래머는 추상화에 의존해야지 구체화에 의존하면 안됨
구현체가 아니라 인터페이스에 의존해야함
위에서 설명한 자동차 예제는 DIP 를 위반한 설계
- OCP, DIP 를 지키면서 설계하기 위해 의존관계 주입 ( DI ) 라는 방법 개발