arcus-java-client
arcus-java-client copied to clipboard
API로 노출하지 않아도 되는 public 메소드의 보호 방안
public class GetFuture<T> implements Future<T> {
private final OperationFuture<Future<T>> rv;
public GetFuture(CountDownLatch l, long opTimeout) {
this.rv = new OperationFuture<Future<T>>(l, opTimeout);
}
public boolean cancel(boolean ign) {
return rv.cancel(ign);
}
public T get() throws InterruptedException, ExecutionException {
Future<T> v = rv.get();
return v == null ? null : v.get();
}
public T get(long duration, TimeUnit units)
throws InterruptedException, TimeoutException, ExecutionException {
Future<T> v = rv.get(duration, units);
return v == null ? null : v.get();
}
public OperationStatus getStatus() {
return rv.getStatus();
}
public void set(Future<T> d, OperationStatus s) {
rv.set(d, s);
}
public void setOperation(Operation to) {
rv.setOperation(to);
}
public boolean isCancelled() {
return rv.isCancelled();
}
public boolean isDone() {
return rv.isDone();
}
}
- 위 클래스에서 set() 메소드와 setOperation() 메소드는 Java Client 내부에서 사용하는 메소드이지만, Package 경로가 다른 클래스에서 호출하기 위해 public으로 선언되었다.
- 문제는 이 메소드가 public으로 선언되었기 때문에 응용에서도 호출할 수 있고, 응용에서 호출하는 경우 Java Client의 비정상적인 동작을 유발할 수 있다.
- Java에는 C#과 같은
프로젝트 내부에서만 호출할 수 있는 접근 제한자
는 존재하지 않아 접근 제한자를 사용해 API로 노출할 메소드만 노출하는 방안은 존재하지 않는다.
- API로 노출할 메소드만 노출하는 방안으로는 interface를 사용하는 방안이 적합해보인다.
- GetFuture를 interface로 변경하고, API로 노출할 메소드만 interface에 선언한 다음, GetFutureImpl 클래스에 기존 GetFuture 클래스의 구현을 옮기는 것이다.
- 이렇게 하면 GetFuture 메소드 중 API로 노출되어 있는 메소드에 한해 하위호환성이 유지되며, API로 노출하지 않을 메소드는 GetFutureImpl 클래스에 존재하기 때문에 내부적으로만 호출할 수 있다.
응용에게 노출되는 Future를 정리해보면 아래와 같습니다.
- OperaionFuture
- CollectionFuture
- GetFuture
- BulkFuture
- SMGetFuture
- BTreeStoreAndGetFuture
- CollectionGetBulkFuture
위 Future들 중 응용이 접근하면 비정상적인 동작을 유발하는 메서드들을 찾아내어 변경할 예정입니다.