다형성과 설계

이동영·2024년 3월 11일

자바 개념정리

목록 보기
19/21

좋은 객체 지향 프로그래밍이란?

  • 추상화 캡슐화 상속 다형성이 있지만 이 중에서 다형성이 제일 중요하다.
  • 객체지향 프로그래밍은 컴퓨터 명령어 목록에서 벗어나 각 독립된 객체들을 만들고 모임으로 만드는 것이다.
  • 각 객체들이 메세지를 주고 받으면서 서로 협력하면서 데이터를 처리하는 것이다.
  • 객체지향 프로그래밍은 유연하고변경이 유용하여 대규모 소프트웨어에서도 이용한다.

유연하고 변경이 용이?

  • 레고 블럭, 키보드 마우스를 교체하듯이 컴퓨터 부품 갈듯이 컴포넌트를 쉽게 쉽게 변경하면서 개발할 수 있는 방법이다.
  • 프로그래밍에서 궁극의 유연함과 변경의 용이성은 바로 객체지향의 꽃인 다형성이다.

다형성의 실세계 비유

  • 실세계를 객체 지향의 세계로 비유하더라도 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인터페이스가 전략을 정의하는 인터페이스이며 각 차량이 전략적인 구현체가 되며 그 전략적 구현체를 클라이언트의 변경 없어 손쉽게 교체할 수 있다.
profile
가치를 제공하는 개발자

0개의 댓글