다형성
>좋은 객체 지향 프로그래밍
객체 지향의 특징은 추상화, 캡슐화, 상속, 다형성 등이 있음.
*객체 지향 프로그래밍- 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위,
즉 "객체"들 의 모임으로 파악. 각각의 객체는 협력해서 메시지를 주고받고, 데이터를 처리할 수 있다.
- 프로그램을 유연하고 변경이 용이하게 만듦(컴포넌트를 쉽고 유연하게 변경하며 개발할 수 있는 방법 ) -> 대규모 소프트웨어 개발에 많이 사용한다.
유연하고 변경이 용이하게 하는 객체지향의 핵심 => "다형성"
>다형성(Polymorphism)
EX1)실세계에 비유해보면 역할(인터페이스)과 구현(인터페이스 구현한 객체)으로 구분,
어떤 사람이 자동차를 사려고 할 때 자동차 역할을 구현한게 차 기종, 운전자가 운전을 할 때 차기종을 바꾼다고 해도 운전자에게는 아무 상관이 없음(=>변경 용이).
-자동차 인터페이스를 따라 차 구현을 한 것, 운전자는 자동차의 역할에 의존하고, 자동차 인터페이스만 알고 있음.
-자동차의 역할과 자동차 구현 왜 분리? ->운전자를 위해 분리. 분리하면 운전자는 자동차의 내부를 알 필요 X. 자동차의 역할만 해당 자동차가 맞춰서 하면 운전자에게 영향 X. ->자동차 세상 무한 확장 가능. 클라이언트에 영향 없이 새로운 기술 제공 가능. =>이는 역할과 구현으로 분리를 했기 때문,
EX2) 공연 시 로미오의 역할은 여러 배우가 가능, 배우 변경과 대체가 가능. 로미오 역할을 하는 배우가 바뀐다고 해서 줄리엣 역할의 배우에게 영향이 X.
=>역할과 구현으로 분리 시 세상이 단순, 유연해지고 변경도 편리해진다. 확장가능한 설계, 클라이언트에 영향 주지 않고 변경 가능.
=>장점: 클라이언트는 대상의 역할(인터페이스)만 알면 된다. 구현체의 내부 구조에 대해서는 몰라도 되고 내부 구조 변경에 영향을 받지 않는다. 구현 대상 자체를 변경해도 영향을 받지 않는다.
*자바 언어의 다형성을 활용 : 역할과 구현 = 인터페이스와 인터페이스를 구현한 클래스(구현 객체).
객체 설계 시 역할과 구현을 명확하게 분리, 역할을 먼저 부여하고, 역할 수행하는 구현 객체 만들기.
"구현보다 인터페이스가 먼저"
+)일반 상속관계도 다형성 가능.
'객체의 협력'이라는 관계를 생각-> 혼자 있는 객체는 없고 /클라이언트가 요청 - 서버가 응답/
->수 많은 객체 클라이언트-객체 서버가 서로 협력 관계. 개념 커지면 서버끼리, 시스템끼리도 가능.
서버인 동시에 클라이언트일 수 0.
응답이 반드시 데이터 값 넣어서 전송하는게 아닐수도 0.
아래 그림에서 빨간 서버가 요청 받아 클라이언트로서 주황 서버한테 요청 하는것도 응답이라 볼 수 있음.
*자바 언어의 다형성 - 오버라이딩(메소드 재정의, 자식 클래스의 필요에 따라 상속된 메소드를 다시 정의)된 메소드가 실행.
다형성으로 구현한 객체를 실행 시점에 유연하게 변경 가능.
+)클래스 상속 관계에서도 다형성, 오버라이딩 적용 가능.
MemberService는 MemberRepository를 의존(의존 한다는 것은 알고 있다는 의미). MemberRepository를 구현한 MemoryMemberRepository와 JdbcMemberRepository를 할당할 수 있음.
//이 부분만 변경해주면 다른 로직 수정없이 변경 가능. 클라이언트나 다른 코드에 영향 X. 확장 설계
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
//이 부분만 변경해주면 다른 로직 수정없이 변경 가능. 클라이언트나 다른 코드에 영향 X. 확장 설계
*다형성의 본질 - 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경. 협력이라는 객체 관계에서 시작해서 다형성의 본질을 이해해야 함. 클라이언트를 변경하지 않고 서버의 구현 기능을 유연하게 변경.
*역할과 구분 분리의 한계- 인터페이스가 변하면 클라이언트, 서버에 큰 변경 필요(ex-자동차를 비행기로 변경 시 다른 면허 필요) =>인터페이스를 안정적으로, 변화가 적게 잘 설계하는게 진짜 중요,