Java 디자인 패턴: 어댑터, 팩토리, 프록시 패턴

어댑터 패턴

전력 공급 장치의 인터페이스를 조정하는 패턴입니다. 예를 들어, 두 개의 전극을 가진 전원 케이블이 세 개의 전극을 지원하는 기기와 호환되지 않을 때, 이 패턴은 두 가지 인터페이스 간의 호환성을 해결합니다.

1. 세 개 전극 인터페이스 정의


public interface ThreePhasePower {
    void supplyThreePhase();
}
            

2. 세 개 전극 구현 클래스


public class ThreePhase implements ThreePhasePower {
    public void supplyThreePhase() {
        System.out.println("세 개 전극으로 전원 공급\n");
    }
}
            

3. 두 개 전극 클래스


public class TwoPhase {
    public void supplyTwoPhase() {
        System.out.println("두 개 전극으로 전원 공급");
    }
}
            

4. 인터페이스 변환 어댑터


public class TwoToThreeAdapter implements ThreePhasePower {
    private final TwoPhase two;
    
    public TwoToThreeAdapter(TwoPhase two) {
        this.two = two;
    }
    
    public void supplyThreePhase() {
        System.out.println("인터페이스 변환 수행");
        two.supplyTwoPhase();
    }
}
            

5. 상속 기반 어댑터


public class InheritanceAdapter extends TwoPhase implements ThreePhasePower {
    public void supplyThreePhase() {
        System.out.println("\n상속 기반 변환 수행");
        this.supplyTwoPhase();
    }
}
            

6. 테스트 클래스


public class Notebook {
    private final ThreePhasePower power;
    
    public Notebook(ThreePhasePower power) {
        this.power = power;
    }
    
    public void charge() {
        power.supplyThreePhase();
    }
    
    public static void main(String[] args) {
        ThreePhasePower direct = new ThreePhase();
        direct.supplyThreePhase();
        
        TwoPhase two = new TwoPhase();
        ThreePhasePower adapted = new TwoToThreeAdapter(two);
        new Notebook(adapted).charge();
        
        adapted = new InheritanceAdapter();
        new Notebook(adapted).charge();
    }
}
            

팩토리 패턴

객체 생성 과정을 추상화하여 사용자에게 생성 로직을 숨기는 패턴입니다. 다양한 옵션을 제공하는 시스템에서 유용하게 활용됩니다.

1. 헤어 타입 인터페이스


public interface HairStyle {
    void applyStyle();
}
            

2. 구체적 헤어 타입


public class LeftPart implements HairStyle {
    public void applyStyle() {
        System.out.println("왼쪽 편발 스타일 적용");
    }
}

public class RightPart implements HairStyle {
    public void applyStyle() {
        System.out.println("오른쪽 편발 스타일 적용");
    }
}
            

3. 팩토리 클래스


public class HairFactory {
    public HairStyle createHair(String type) {
        switch (type.toLowerCase()) {
            case "left": return new LeftPart();
            case "right": return new RightPart();
            default: throw new IllegalArgumentException("Unsupported style");
        }
    }
    
    public HairStyle createByClass(String className) {
        try {
            return (HairStyle) Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Class creation failed", e);
        }
    }
}
            

4. 테스트 클래스


public class HairTest {
    public static void main(String[] args) {
        HairStyle left = new LeftPart();
        HairStyle right = new RightPart();
        left.applyStyle();
        right.applyStyle();
        
        HairFactory factory = new HairFactory();
        factory.createHair("left").applyStyle();
        factory.createByClass("RightPart").applyStyle();
    }
}
            

프록시 패턴

특정 객체에 대한 접근을 제어하는 중개자 역할을 수행하는 패턴입니다. 추가 기능을 동적으로 추가하거나 접근 제어가 필요한 경우 유용합니다.

1. 이동 가능한 인터페이스


public interface Movable {
    void move();
}
            

2. 차량 클래스


public class Car implements Movable {
    public void move() {
        try {
            System.out.println("차량 이동 중");
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
            

3. 시간 기록 프록시


public class TimeTrackingProxy implements Movable {
    private final Movable target;
    
    public TimeTrackingProxy(Movable target) {
        this.target = target;
    }
    
    public void move() {
        long startTime = System.currentTimeMillis();
        System.out.println("이동 시작");
        target.move();
        long endTime = System.currentTimeMillis();
        System.out.println("이동 종료 - 소요 시간: " + (endTime - startTime) + "ms");
    }
}
            

4. 로깅 프록시


public class LoggingProxy implements Movable {
    private final Movable target;
    
    public LoggingProxy(Movable target) {
        this.target = target;
    }
    
    public void move() {
        System.out.println("로그 시작");
        target.move();
        System.out.println("로그 종료");
    }
}
            

5. JDK 동적 프록시


public class TimeHandler implements InvocationHandler {
    private final Object target;
    
    public TimeHandler(Object target) {
        this.target = target;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        System.out.println("이동 시작");
        Object result = method.invoke(target, args);
        long endTime = System.currentTimeMillis();
        System.out.println("이동 종료 - 소요 시간: " + (endTime - startTime) + "ms");
        return result;
    }
}
            

태그: java DesignPatterns AdapterPattern FactoryPattern ProxyPattern

8월 8일 05:53에 게시됨