프록시는 대리인이라는 뜻으로 프록시 패턴은 클라이언트가 객체를 직접 참조하는 것이 아니라 proxy(대리인)를 통해 객체에 접근하는 패턴입니다.
구조와 글만 보면 이해하기 어려우니 예제를 통해 자세히 알아보겠습니다.
public class Company {
public void enter() {
System.out.println("들어 가기");
}
}
해당 코드에서 만약 직원들만 회사에 들어갈 수 있다는 조건이 추가된다면 코드가 어떻게 수정될까요?
public class Company {
public void enter(String status) {
if ("employee".equals(status) {
System.out.println("들어 가기");
}
}
}
if문을 추가해서 직원일 경우에만 들어가게 코드를 수정할 수 있습니다. 하지만 이런 식으로 수정하면 enter() 라는 메서드가 인증 기능까지 수행하게 되고 메서드의 변경 포인트가 증가하게 됩니다. 이럴 때 proxy를 사용하면 기존에 코드를 수정하지 않고 새로운 기능을 추가할 수 있습니다.
public enum Status {
EMPLOYEE, GUEST
}
public interface Company {
void enter(Status status);
}
public class MyCompany implements Company {
@Override
public void enter(Status status) {
System.out.println(status + "들어가기");
}
}
EMPLOYEE, GUEST라는 enum을 추가하고 Company 인터페이스를 구현한 MyCompany 클래스를 만들었습니다.
@RequiredArgsConstructor
public class CompanyProxy implements Company {
private final Company company;
@Override
public void enter(Status status) {
if (Status.GUEST == status) {
throw new IllegalArgumentException("손님은 들어갈 수 없습니다.");
}
company.enter(status);
}
}
그리고 Company 인터페이스를 구현한 CompanyProxy 클래스를 만들었습니다. 멤버 변수로는 Company 타입을 가지고 있습니다. proxy객체에서 인증을 처리하고 company.enter(status)를 호출하는 것을 확인할 수 있습니다. 즉 객체에 직접 접근하지 않고 proxy를 통해 접근해서 기존 코드를 수정하지 않고 새로운 기능을 proxy에 위임했습니다.
Proxy를 테스트해 보겠습니다.
class ProxyTest {
@Test
public void enter() {
// given
Company myCompany = new MyCompany();
CompanyProxy proxy = new CompanyProxy(myCompany);
// when
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
proxy.enter(Status.GUEST);
});
// then
assertThat(exception.getMessage()).isEqualTo("손님은 들어갈 수 없습니다.");
}
}
CompanyProxy를 생성할 때 실제 기능을 수행하는 myCompany 인스턴스를 넘겨줍니다.
클라이언트에서는 proxy를 통해 enter 메서드를 수행합니다.
즉, 클라이언트 → myCompany를 호출하는 것이 아닌 중간에 proxy를 두어서
클라이언트 → proxy(인증) → myCompany(출입) 기존에 코드를 수정하지 않고 인증을 proxy에서 처리하게 하여 SRP를 지킬 수 있게 됩니다.
프록시는 인증뿐만 아니라 초기화 지연, 접근 제어, 로깅, 캐싱 등 다양하게 응용이 가능합니다.
마지막으로 프록시 패턴의 장단점을 설명하고 포스팅을 마치겠습니다.
장점
- 기존 코드를 수정하지 않고 사용할 수 있다.
- 기존 코드가 해야 하는 일만 할 수 있다. (SRP)
- 기능 추가 및 초기화 지연 등으로 다양하게 활용할 수 있다.
단점
- 코드의 복잡도가 증가한다.
'디자인 패턴' 카테고리의 다른 글
브릿지 패턴(Bridge Pattern) (0) | 2022.01.29 |
---|---|
팩토리 메소드 패턴(Factory method pattern) (0) | 2021.01.21 |
싱글톤 패턴(Singleton pattern) (0) | 2021.01.11 |
전략 패턴 (Strategy pattern) (0) | 2021.01.09 |
객체지향 SOLID 원칙 (0) | 2020.12.27 |
댓글