Telescoping Parameter 패턴은 "켄트 벡의 구현 패턴"에도 언급되었던 패턴이다.
기본적으로 이 패턴은 다수의 매개 변수를 가진 함수의 문제점을 해결하기 위한 패턴이다.
보통 생성자가 다수의 매개 변수 개수를 달리 하면서 생성이 가능한 경우에 주로 사용된다.
실제로도 많이 쓰이는 패턴이라서 Java 라이브러리의 ServerSocket 함수를 가지고 설명을 해볼까 한다.
우선 API를 기준으로 보면 Telescoping Parameter 패턴의 외형은 다음과 같다.
public ServerSocket(int port);
public ServerSocket(int port, int backlog);
public ServerSocket(int port, int backlog, InetAddress bindAddr);
이처럼 매개 변수가 여럿이고 매개변수의 기본 값이 있는 경우에 인자 개수가 다른 API를 제공해 준다. 이렇게 하면 사용하는 입장에서는 필요에 따라 짧거나 긴 매개 변수를 가진 API를 호출할 수 있다. 이 모양이 마치 망원경을 접었다 폈다 하는 모양과 비슷하다고 해서 붙여진 이름이다.
내부 구현 시 고려 사항
이 패턴에 대해서는 다음과 같은 사항을 잘 생각해 봐야 한다. 이는 내부 구현에 있어서 지켜야 할 중요한 부분이다.
저 함수들은 모두 backlog 변수나 bindAddr 변수에 대한 기본 값이 있다는 전제 하에서 작성되었다. 따라서 결과적으로는 세 함수 모두 세 개의 파라메터 모두에 대한 설정을 하게 될 것이다.
이런 상황에서 매개 변수로 하려는 일은 동일할텐데 이를 각 함수에 구현하면 중복 구현의 문제가 발생한다. 따라서 아래와 같은 형태로 내부를 구현해 주어야 한다.
public ServerSocket(int port){
this(port, 50, null);
}
public ServerSocket(int port, int backlog){
this(port, backlog, null);
}
/* 결국 어떤 함수를 사용해도 아래 함수가 호출되게 된다 */
public ServerSocket(int port, int backlog, InetAddress bindAddr){
setImpl();
bind(new InetSocketAddress(bindAddr, port), backlog);
}
실제 코드보다는 좀 더 간단하게 변경하였다. 매개 변수가 한 개인 경우 남은 두개의 기본 값을 채워 3개짜리 함수를 호출한다. 두 개짜리고 마찬가지로 3개짜리 함수를 호출하는 것으로 할 일을 마친다. 3개짜리 함수만 실제 필요한 동작을 수행하게 된다.
코드 중복의 방지
객체의 외부에서 객체로 변수 값을 직접 전달하는 기본 방식은 setter를 이용하는 것이다. 하지만 종종 생성자를 이용하여 변수를 초기에 셋팅하게 하는 것이 좋을 때가 있다. 이렇게 되면 생성자와 setter에 의해 변수가 셋팅되게 된다. 변수 셋팅은 아주 중요한 작업이다. 이 경우 생성자 내부에서는 setter를 호출해 주는 것이 좋다.
안티 패턴
class Example {
int data;
public void Example(int data){
this.data = data;
}
public void setData(int data){ this.data = data; }
}
이렇게 구현했을 경우 setData 내부에서 data가 새로 설정된 이후 동작을 변경해버리면 생성자를 통해 data를 변경했을 때에는 이것이 반영되지 않는다. 따라서 아래와 같이 구현하는 것이 좋다.
좋은 구현 방식
class Example {
int data;
public void Example(int data){
setData(data); // 이렇게 해야 setData() 함수 내부의 변경에 안전하다.
}
public void setData(int data){ this.data = data; }
}
이 문제에 대한 고려가 Telescoping Parameter 패턴의 구현에도 고스란히 반영되어 있다.
단순히 자꾸 함수를 호출하려는 것으로만 보일지 모르겠지만 실제로는 모든 함수들은 모든 매개 변수가 설정되는 것을 기대하고 있다. 따라서 매개 변수로 내부 변수를 설정하는 코드(예제에서는 bind() 함수를 호출하는 부분)는 한 곳으로 몰아 주기 위해 this 함수를 호출하는 것이다.
Telecoping Parameter 패턴을 구현할 때에는 이 점을 꼭 염두해 두어야 한다.
'5.디자인패턴' 카테고리의 다른 글
Pluggable Selector 패턴 (1) | 2016.08.21 |
---|---|
State 패턴 (0) | 2016.08.15 |
Strategy 패턴 (0) | 2016.08.15 |
interface -abstract class - concrete class 패턴(인터페이스 구현 중복 해결 패턴) (2) | 2016.08.10 |
Enum Factory Method 패턴 (0) | 2016.08.07 |