💡 프록시(Proxy) = 크로스컷팅 관심사(Cross-Cutting Concern)를 제공

프록시 패턴(Proxy Pattern)대리 객체를 통해 원래 객체에 대한 접근을 제어하는 디자인 패턴입니다. 이 패턴은 주로 크로스컷팅 관심사(Cross-Cutting Concern)를 처리하는 데 사용됩니다.

크로스컷팅 관심사(Cross-Cutting Concern):

  • 크로스컷팅 관심사는 애플리케이션의 주요 비즈니스 로직과는 직접적인 관련이 없지만, 다양한 모듈에서 반복적으로 나타나는 공통 기능을 말합니다. 대표적인 예로 로그 기록, 트랜잭션 관리, 보안 검사, 캐싱, 모니터링 등이 있습니다.
  • 이러한 기능을 각 비즈니스 로직에 직접 포함시키는 대신, 프록시를 사용하여 비즈니스 로직에 영향 없이 해당 기능을 추가할 수 있습니다. 이를 통해 모듈 간의 관심사 분리가 가능해집니다.

프록시의 역할:

  • 프록시는 원래 객체를 감싸고 있으며, 객체에 접근할 때 추가적인 작업(크로스컷팅 관심사)을 수행할 수 있습니다.
  • 예를 들어, 데이터베이스 작업 전후에 트랜잭션을 처리하거나, 메서드 호출 전후에 로그를 기록할 수 있습니다. 이 작업은 실제 비즈니스 로직을 수행하는 원래 객체에는 영향을 미치지 않습니다.

예시: 스프링 AOP(Aspect-Oriented Programming)와 프록시

스프링 프레임워크에서는 AOP(Aspect-Oriented Programming)를 통해 프록시를 사용하여 크로스컷팅 관심사를 처리합니다. 예를 들어, 특정 메서드 실행 전후로 로깅을 하거나, 메서드 실행 시 트랜잭션 처리를 추가하는 등의 작업을 프록시를 통해 수행할 수 있습니다.

public class ServiceProxy implements MyService {
    private MyService target;

    public ServiceProxy(MyService target) {
        this.target = target;
    }

    @Override
    public void doSomething() {
        System.out.println("Logging before method call");
        target.doSomething();  // 실제 비즈니스 로직 호출
        System.out.println("Logging after method call");
    }
}

위 예시에서는 프록시 객체가 원래의 MyService 객체를 감싸고 있으며, 메서드 실행 전후에 로깅 작업을 추가하고 있습니다. 이렇게 크로스컷팅 관심사를 처리할 수 있습니다.


💡 어댑터(Adapter) = 특정 기능을 추가

어댑터 패턴(Adapter Pattern)호환되지 않는 인터페이스를 가진 객체들 사이에 상호작용을 가능하게 하는 디자인 패턴입니다. 즉, 어댑터는 기존의 인터페이스에 특정 기능을 추가하여 새로운 요구사항을 충족할 수 있도록 도와줍니다.

어댑터의 역할:

  • 어댑터는 기존 클래스 또는 인터페이스를 변경하지 않고, 다른 형식의 객체와 통신할 수 있도록 새로운 기능을 추가합니다.
  • 즉, 호환되지 않는 인터페이스나 기존 기능에 새로운 기능을 덧붙여서 작동하도록 만듭니다. 이를 통해 새로운 클라이언트가 기존 클래스를 사용할 수 있도록 합니다.

예시: 어댑터 패턴

// 기존 인터페이스
public interface OldInterface {
    void oldMethod();
}

// 새로운 인터페이스
public interface NewInterface {
    void newMethod();
}

// 어댑터 클래스
public class Adapter implements NewInterface {
    private OldInterface oldInterface;

    public Adapter(OldInterface oldInterface) {
        this.oldInterface = oldInterface;
    }

    @Override
    public void newMethod() {
        System.out.println("New method call");
        oldInterface.oldMethod();  // 기존 메서드 호출
    }
}

위 코드에서 어댑터는 기존의 OldInterface를 감싸고 있으며, 새로운 요구사항에 맞는 NewInterface를 구현합니다. 이를 통해 기존 클래스를 수정하지 않고 새로운 기능을 추가하는 것이 가능합니다.

어댑터 패턴의 활용:

  • 기존 시스템을 변경하지 않고, 새로운 기능유연하게 추가해야 할 때 사용됩니다. 예를 들어, 새로운 데이터베이스나 파일 시스템을 사용하는 경우, 기존 인터페이스에 대한 호환성을 유지하면서 새로운 기능을 덧붙이는 데 어댑터 패턴이 유용합니다.

💡 프록시와 어댑터의 차이점

특징 프록시(Proxy) 어댑터(Adapter)
주된 목적 기존 객체에 추가적인 기능(크로스컷팅 관심사) 제공 호환되지 않는 인터페이스 간의 호환성 추가
동작 방식 원래 객체를 감싸고, 그 전후에 추가 작업 수행 기존 객체와 호환성 유지하며 새로운 인터페이스 구현
사용 사례 AOP, 보안 검사, 트랜잭션, 로깅 등 기존 시스템에 새로운 기능 추가, 인터페이스 통합
영향을 받는 객체 원래 객체에 간접적으로 접근 기존 객체에 변화를 주지 않고 새로운 인터페이스로 감싸줌

결론

  • 프록시 패턴은 객체를 대리하여 크로스컷팅 관심사(트랜잭션 관리, 로깅, 보안 등)를 처리하는 데 사용되며, 주로 AOP 같은 기술에서 활용됩니다.
  • 어댑터 패턴은 호환되지 않는 인터페이스를 호환 가능하게 만들고, 기존 객체에 새로운 기능을 추가하는 역할을 합니다. 기존 시스템을 변경하지 않고 새로운 기능을 추가할 때 유용합니다.

'Spring Framework' 카테고리의 다른 글

Redirect(리다이렉트)  (0) 2024.10.10
핸들러 메서드(Handler Method) - 컨트롤러  (0) 2024.10.10
스프링 웹 MVC  (0) 2024.10.08
필터와 밸브  (0) 2024.10.08
AJP 커넥터  (1) 2024.10.08

+ Recent posts