본문 바로가기

Pattern/GOF

구조패턴 - 프록시

반응형

1. 프록시 패턴이란?

일반적으로 프록시는 다른 무언가와 이어지는 인터페이스의 역할을 하는 클래스이다. 프록시는 어떠한 것(이를테면 네트워크 연결, 메모리 안의 커다란 객체, 파일, 또 복제할 수 없거나 수요가 많은 리소스)과도 인터페이스의 역할을 수행할 수 있다.

쉽게 말해 특정 객체에 대한 접근을 제어하거나 기능을 추가할 수 있는 패턴이다.

 

2. 샘플코드

유저가 로그인 할 때 프록시에 아이디와 패스워드를 캐싱하여 접근 권한을 판단할 수 있는 기능을 만들어보겠다.

억지스러운 코드긴 하지만 중간에 대리자가 있다는 개념 위주로 이해하면 될 것 같다.

 

RepositoryService

public interface RepositoryService
{
    boolean loginUser(String id, String password);
    String getUserInfo(String id);
}

로그인과 유저의 정보를 확인할 수 있는 api를 제공

 

RemoteRepository

public class RemoteRepository implements RepositoryService
{
    private String mId = "hinos";
    private String mPassword = "1234";
    private String mCountry = "kr";

    @Override
    public boolean loginUser(String id, String password) {
        return this.mId.equals(id) && mPassword.equals(password);
    }

    @Override
    public String getUserInfo(String id) {
        return mId + "|" + mPassword + "|" + mCountry;
    }
}

Server측 api를 호출할 수 있는 클래스이다.

id와 password, country의 값은 서버 DB에 저장되어 있는 유저 정보라고 생각하면 된다. 

 

ProxyRepository

public class ProxyRepository implements RepositoryService
{
    private RepositoryService mService;
    private ConcurrentHashMap<String, String> mUserCache = new ConcurrentHashMap<>();

    public ProxyRepository(RepositoryService service) {
        this.mService = service;
    }

    @Override
    public boolean loginUser(String id, String password) {
        boolean isSuccess = mService.loginUser(id, password);
        if (isSuccess && !mUserCache.contains(id))
            mUserCache.put(id, password);
        return isSuccess;
    }

    @Override
    public String getUserInfo(String id) {
        if (!mUserCache.containsKey(id))
            throw new SecurityException("you do not have access rights.");
        return mService.getUserInfo(id);
    }
}

프록시에서는 RemoteRepository에서 로그인한 결과를 통지 받고 유저 정보를 캐싱하게 된다.

getUserInfo를 호출했을 때 캐싱한 유저 데이터가 있을 때는 서버의 유저 정보를 알려주고 권한이 없는 유저에게는 SecurityException을 던지게 된다.

 

Client

public class Client
{
    public static void main(String[] args) {
        RepositoryService service = new ProxyRepository(new RemoteRepository());
        service.loginUser("hinos", "1234");
        System.out.println(service.getUserInfo("hinos"));

        System.out.println(service.getUserInfo("son"));
    }
}

 

 

이처럼 구현체 중간에 특정한 대리자를 두어 보다 유연하게 객체를 핸들링 할 수 있게 된다.

반응형

'Pattern > GOF' 카테고리의 다른 글

행위패턴 - 옵저버패턴  (0) 2022.06.09
행위패턴 - 책임 연쇄 패턴  (0) 2022.05.31
구조패턴 - 데코레이션 패턴  (0) 2022.05.24
구조패턴 - 컴포짓패턴  (0) 2022.05.23
생성패턴 - 팩토리메서드  (0) 2022.05.11