좋은 객체 지향 프로그래밍이란?
- 추상화 캡슐화 상속 다형성이 있지만 이 중에서 다형성이 제일 중요하다.
- 객체지향 프로그래밍은 컴퓨터 명령어 목록에서 벗어나 각 독립된 객체들을 만들고 모임으로 만드는 것이다.
- 각 객체들이 메세지를 주고 받으면서 서로 협력하면서 데이터를 처리하는 것이다.
- 객체지향 프로그래밍은 유연하고변경이 유용하여 대규모 소프트웨어에서도 이용한다.
유연하고 변경이 용이?
- 레고 블럭, 키보드 마우스를 교체하듯이 컴퓨터 부품 갈듯이 컴포넌트를 쉽게 쉽게 변경하면서 개발할 수 있는 방법이다.
- 프로그래밍에서 궁극의 유연함과 변경의 용이성은 바로 객체지향의 꽃인 다형성이다.
다형성의 실세계 비유
- 실세계를 객체 지향의 세계로 비유하더라도 1:1 매칭은 안된다. 하지만 그래도 비유를 하면 이해를 하기 좋다.
- 역활과 구현으로 세상을 구분한다.
- 예를들어 자동차가 있으면 나는 운전면허 하나만 있으면 어떤 자동차든지 탑승이 가능하다. 왜냐하면 자동차의 규격이 있기에 하나를 운전할 줄 알면 그 규격대로 만들어진 자동차는 운전이 가능하다. 이 규격은 물론 자동차 제조업체에게도 좋은 가이드 라인이 되기 때문이다. 하지만 더 근본적인 이유는 차량이 바뀌어도 운전자의 역활은 바뀌지 않기 때문이다.
- 자동차에 역활을 부여한것은 자동차 운전자인 나를 위해서이다. 자동차의 기본적인 역활만 알고 있으면 자동차라는 구현체는 무한하게 이용할 수 있다.
공연 무대(로미오와 줄리엣)
- 로미엣과 줄리엣을 공연하는데 여기서 연기하는 배우들은 대체가 가능하다.
- 줄리엣 역활을 하는 김태희 혹은 송혜교 배우가 있는데 둘다 사정이 생겨서 공연을 하지 못하게 되더라도 무명 배우로 대체가 가능하다.
- 로미오와 줄리엣이라는 것을 역활로 구분하면 구현하는 객체를 대체가 가능하다.
- 로미엣을 맡은 장동건은 상대 배역인 줄리엣의 배역이 누가 오든지간에 로미엣 역활에만 출실히 하면 된다. 줄리엣은 로미오가 바뀌든 영향을 주지 않기 때문이다.
역활과 구현을 분리
- 역활이라는 인터페이스와 구현 클래스를 분리하는것이 세상이 단순해지며 유연해지며 변경이 용이 해진다.
- 역활과 구현을 분리한다면 클라이언트는 역활만 파악하면 된다. 운전자는 역활이라는 자동차(운전하는 방법)을 알게되면 어느 자동차가 오더라도 역활을 파악한 클라이언트는 운전이 가능하다.
- 역활의 내부 구조가 바뀌어도 클라 입장에서는 영향이 없다. 자동차의 부품을 교체하더라도 운전자는 무리없이 운전이 가능하다.
자바 언어
- 역할 = 인터페이스
- 구현 = 인터페이스를 구현한 클래스 혹은 구현 객체
- 객체를 설계시 역할인 인터페이스를 부여하고 그 역활을 수행하는 구현 객체를 분리한다.
객체의 협력이라는 관계부터 생각
- 다형성의 본질을 이해하기 위해서는 클라이언트와 서버라는 단어의 이해가 필요하다.
- 실제로 물리적인 서버 물리적인 클라(고객)이 아닌 객체끼리 요청하는것이 클라이언트가 되며 그 요청을 응답하는것 객체가 서버가 될 수 있다.

- 수 많은 객체는 클라이언트와 서버로 나뉠 수 있다.
- 객체는 클라이언트임과 동시에 서버가 될 수 있다. 서버객체는 클라이언트로 요청을 받고 그에 필요한 데이터를 응답하기 위해서 또 다른 서버 객체에게 요청을 보내서 응답받을 수 있다.
다형성의 본질
- 인터페이스를 구현한 객체를 실행시점에 유연하게 변경이 가능하다.(아직 이뜻이 50%밖에 이해가 안됨)
- 다형성의 본질을 이해하기 위해서는 협력이라는 객체사이의 관계에서 시작해야한다.

- 클라이언트 코드를 변경하지 않으면서 섭의 구현 기능을 유용하게 변경할 수 있다.
- 예를들어 클라이언트인 메인메소드에서 조건에 따라 메소드에 구현체인 객체를 넘겨주면 구현 기능들을 유연하게 변경이 가능하다.
- 드라이버가 K3를 타다가 조건에 의해 모텔3자동차를 탈수도 있게 된다.
정리
- 역활과 구현으로 분리하여 실세계의 장점을 객체지향으로 가져올 수 있다.
- 유연하며 확장가능한 설계를 할 수 있다. 확장가능한 설계는 자동차 인터페이스를 구현하여 수만은 자동차 구현 클래스들을 만들어 낼 수 있다.
- 인터페이스를 안정적으로 설계하는것이 중요하다.
- 자바는 다형성이 가장 중요하다.
- 디자인 패턴은 다형성을 활용한다.
- 스프링의 핵심인 제어의 역전IOC DI도 다형성을 활용한다.
- 다형성을 활용하면 레고 조립하듯이 편하게 변경할 수 있다.
한계
- 인터페이스를 안정적으로 설계하지 않을 경우 문제가 생겨 자동차를 타다가 비행기를 타야하면 비행기 라이센스를 다시 취득해야하듯이 인터페이스를 다시 설계해야한다.
- 대본 자체가 변경이 되면 배우는 역할인 대본에 대한 숙지를 할 필요가 있다.
- 인터페이스가 변하지 않고 안정적으로 잘 설계하는것이 중요하다.
OCP(Open-Closed Principle)원칙
- 좋은 객체지향 설계의 원칙 중 하나로 OCP원칙이 있다.
- open for extrension : 새로운 기능의 추가나 변경사항이 생겼을 때 기존코드는 확장할 수 있어야 한다.
- Closed for modification : 기존의 코드는 수정할 수 없다.
확장에 열려있다는 의미
- 새로운 차량을 추가하더라도 Driver 클래스의 코드의 변경은 1도 없었다.
- main()을 제외한 핵심코드 Driver코드는 1도 수정을 하지 않는다.
- 확장이 열려있다는 의미는 Car인터페이스를 활용하여 무한하게 자동차를 구현하여 새로운 기능을 추가할 수 있으며 구현된 차량을 자유롭게 호출할 수 있는것이다.
코드 수정은 닫혀있다는 의미
- 새로운 차량이 추가 되면 기존 코드의 수정은 불가피 하다. 그렇기에 변하는 부분과 변하지 않는 부분을 따로 나누어야 한다.
변하지 않는 부분
- 새로운 자동차를 추가할 때 가장 영향을 많이 받는 클라이언트는 Car의 기능을 사용하고 있는 Driver클래스 이다.
- Car 인터페이스를 사용하고 있는 Driver클래스는 코드 수정없이 Car인터페이스의 구현체들을 사용할 수 있다. 이것이 바로 Closed for modification이다.
- 클라이언트 코드를 바꾸지 않는다.
변하는 부분
- Main()과 같이 차량을 추가하고 클라이언트에게 차량을 전달해주기 위해서는 OCP원칙을 지키더라도 코드변경이 필요하다.
- main()은 전체 프로그램을 설정하고 조율하는 역활을 하기에 코드 수정이 불가피하다.
정리
- Car를 사용하는 Driver의 코드의 변경 없이 자동차를 확장할 수 있다.(클라이언트 코드)
- 다형성을 활용하여 역할과 구현을 분리하였기에 새로운 자동차를 추가하여도 대부분의 핵심코드를 잘 유질할 수 있다.]
전략패턴Strategy Patterrn)
- 알고리즘을 클라이언트의 코드의 변경 없이 쉽게 변경할 수 있다.
- Car인터페이스가 전략을 정의하는 인터페이스이며 각 차량이 전략적인 구현체가 되며 그 전략적 구현체를 클라이언트의 변경 없어 손쉽게 교체할 수 있다.