본문 바로가기

WEB개발/Pattern

DelegationPattern

정의

Business delegate pattern은 Java EE design pattern의 하나로 특정 케이스마다 처리해야 하는 로직이 틀린 경우에 사용이 되는 패턴입니다. 

 

아래 구조를 보면 클라이언트는 Business delegate에게 이런 비즈니스 로직을 수행하겠어 요청을 하면  Lookup Service가 상황에 맞는 비즈니스클래스를 룩업해 로직을 수행하도록 합니다.

Structure

  • Business delegate - client가 특정 서비스를 요청할 클래스 (비즈니스 로직 안가지고 있음)
  • Lookup Service - delegate가 호출하는 클래스로 특정 케이스마다 처리를 담당하는 실제 구현체를 반환
  • Business Service - 실제 사용될 서비스 인터페이스로 실제 비즈니스 로직은 이 클래스를 구현을 해야 함

Implementation

1. Business Service Interface

서비스의 공통 인터페이스입니다. 비즈니스 로직을 처리하는 실제 구현체들은 이 인터페이스를 구현합니다.

public interface BusinessService { void execute(); }

2. Concrete Implementations of Business Service

실제 비즈니스 로직을 구현한 클래스들입니다.

public class ECommerceService implements BusinessService {
    @Override
    public void execute() {
        System.out.println("Executing E-Commerce Service");
    }
}

public class PaymentService implements BusinessService {
    @Override
    public void execute() {
        System.out.println("Executing Payment Service");
    }
}

3. Lookup Service

특정 케이스에 따라 적절한 비즈니스 서비스를 반환하는 역할을 합니다.

public class BusinessLookupService {
    public BusinessService getBusinessService(String serviceType) {
        if ("ECommerce".equalsIgnoreCase(serviceType)) {
            return new ECommerceService();
        } else if ("Payment".equalsIgnoreCase(serviceType)) {
            return new PaymentService();
        }
        return null;
    }
}

 

4. Business Delegate

BusinessLookupService를 사용해 적절한 비즈니스 서비스를 찾고 클라이언트의 요청을 위임합니다.

public class BusinessDelegate {
    private BusinessLookupService lookupService = new BusinessLookupService();
    private BusinessService businessService;
    private String serviceType;

    public void setServiceType(String serviceType) {
        this.serviceType = serviceType;
    }

    public void doTask() {
        businessService = lookupService.getBusinessService(serviceType);
        if (businessService != null) {
            businessService.execute();
        } else {
            System.out.println("Invalid service type: " + serviceType);
        }
    }
}

5. Client

BusinessDelegate를 통해 간단하게 서비스를 요청합니다.

public class Client {
    private BusinessDelegate businessDelegate;

    public Client(BusinessDelegate businessDelegate) {
        this.businessDelegate = businessDelegate;
    }

    public void performTask() {
        businessDelegate.doTask();
    }
}

 

6. Main Class

전체 동작을 확인하는 테스트 코드입니다.

public class Main {
    public static void main(String[] args) {
        BusinessDelegate businessDelegate = new BusinessDelegate();

        // 클라이언트 생성
        Client client = new Client(businessDelegate);

        // E-Commerce 서비스 호출
        businessDelegate.setServiceType("ECommerce");
        client.performTask();

        // Payment 서비스 호출
        businessDelegate.setServiceType("Payment");
        client.performTask();

        // 유효하지 않은 서비스 호출
        businessDelegate.setServiceType("Unknown");
        client.performTask();
    }
}
 

 


예시

 

1. 로그 시스템에서의 위임

로그 시스템에서는 실제로 로그를 기록하는 구현을 다른 객체에 위임하는 방식으로 Delegation 패턴이 자주 사용됩니다.

 

public interface Logger {
    void log(String message);
}

public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("ConsoleLogger: " + message);
    }
}

public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        // 파일에 로그 기록 로직
        System.out.println("FileLogger: " + message);
    }
}

public class AppLogger {
    private Logger logger;

    public AppLogger(Logger logger) {
        this.logger = logger;
    }

    public void log(String message) {
        logger.log(message); // 위임
    }
}

public class Main {
    public static void main(String[] args) {
        Logger consoleLogger = new ConsoleLogger();
        Logger fileLogger = new FileLogger();

        AppLogger appLogger = new AppLogger(consoleLogger);
        appLogger.log("This is a console log");

        appLogger = new AppLogger(fileLogger);
        appLogger.log("This is a file log");
    }
}

 

 

2. Spring의 AOP와 Delegation

Spring의 AOP(Aspect-Oriented Programming)에서 메서드 호출의 실제 처리는 프록시 객체가 원래 객체에게 위임하는 방식으로 동작합니다.

 

3. UI 컴포넌트 개발

UI 라이브러리에서 이벤트 처리는 Delegation 패턴의 대표적인 사용 사례입니다. 자바 Swing에서는 이벤트 리스너가 버튼 클릭 이벤트를 처리하도록 위임합니다.

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonExample {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Example");
        JButton button = new JButton("Click Me");

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button was clicked!");
            }
        });

        frame.add(button);
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

 


https://jaepils.github.io/pattern/2018/07/24/pattern-delegate.html

 

'WEB개발 > Pattern' 카테고리의 다른 글

Proxy Pattern  (0) 2021.09.24
[PATTERN] Producer - Consumer  (0) 2021.08.27
Adapter Pattern  (0) 2021.07.14