수색…


어댑터 패턴 (PHP)

다른 유형의 조직에서 특정 루틴을 수행하는 과학 실험을 사용하는 실제 사례입니다. 클래스에는 기본적으로 조직 또는 루틴을 개별적으로 가져 오는 두 개의 함수가 포함되어 있습니다. 이후 버전에서는 새로운 클래스를 사용하여 두 클래스를 모두 가져 오는 함수를 추가했습니다. 즉, 원래 코드를 편집하지 않았으므로 기존 클래스를 손상시킬 위험이 없습니다 (다시 테스트하지 않아도 됨).

class Experiment {
    private $routine;
    private $tissue;
    function __construct($routine_in, $tissue_in) {
        $this->routine = $routine_in;
        $this->tissue  = $tissue_in;
    }
    function getRoutine() {
        return $this->routine;
    }
    function getTissue() {
        return $this->tissue;
    }
}

class ExperimentAdapter {
    private $experiment;
    function __construct(Experiment $experiment_in) {
        $this->experiment = $experiment_in;
    }
    function getRoutineAndTissue() {
        return $this->experiment->getTissue().' ('. $this->experiment->getRoutine().')';
    }
}

어댑터 (Java)

귀하의 현재 코드베이스에는 다음과 같은 MyLogger 인터페이스가 있다고 가정합니다 :

interface MyLogger {
    void logMessage(String message);
    void logException(Throwable exception);
}

MyFileLoggerMyConsoleLogger 와 같이 이들에 대한 몇 가지 구체적인 구현을 작성했다고 가정 해 MyFileLogger .

응용 프로그램의 Bluetooth 연결을 제어하기위한 프레임 워크를 사용하기로 결정했습니다. 이 프레임 워크에는 다음 생성자가있는 BluetoothManager 가 들어 있습니다.

class BluetoothManager {
    private FrameworkLogger logger;

    public BluetoothManager(FrameworkLogger logger) {
        this.logger = logger;
    }
}

BluetoothManager 는 로거도 허용합니다. 그러나 인터페이스가 프레임 워크에 의해 정의 된 로거가 필요하며 함수의 이름을 다르게 지정하는 대신 메소드 오버로드를 사용했습니다.

interface FrameworkLogger {
    void log(String message);
    void log(Throwable exception);
}

재사용하고 싶은 MyLogger 구현체가 이미 있지만, FrameworkLogger 의 인터페이스에 맞지 않습니다. 어댑터 디자인 패턴이 나오는 곳입니다.

class FrameworkLoggerAdapter implements FrameworkLogger {
    private MyLogger logger;

    public FrameworkLoggerAdapter(MyLogger logger) {
        this.logger = logger;
    }

    @Override
    public void log(String message) {
        this.logger.logMessage(message);
    }

    @Override
    public void log(Throwable exception) {
        this.logger.logException(exception);
    }
}

FrameworkLogger 인터페이스를 구현하고 MyLogger 구현을 수용하는 어댑터 클래스를 정의하면이 기능을 다른 인터페이스간에 매핑 할 수 있습니다. 이제 BluetoothManager MyLogger 구현과 함께 사용할 수 있습니다.

FrameworkLogger fileLogger = new FrameworkLoggerAdapter(new MyFileLogger());
BluetoothManager manager = new BluetoothManager(fileLogger);

FrameworkLogger consoleLogger = new FrameworkLoggerAdapter(new MyConsoleLogger());
BluetoothManager manager2 = new BluetoothManager(consoleLogger);

Java 예제

SWT MouseListenerMouseAdapter 클래스에서 Adapter 패턴의 훌륭한 기존 예제를 찾을 수 있습니다.

MouseListener 인터페이스는 다음과 같습니다.

public interface MouseListener extends SWTEventListener {
    public void mouseDoubleClick(MouseEvent e);
    public void mouseDown(MouseEvent e);
    public void mouseUp(MouseEvent e);
}

이제 UI를 작성하고 이러한 리스너를 추가하는 시나리오를 상상해보십시오.하지만 대부분의 경우에는 무언가가 클릭 한 번 (mouseUp)이 아닌 다른 것을 신경 쓰지 않습니다. 빈 구현을 끊임없이 만들고 싶지는 않을 것입니다.

obj.addMouseListener(new MouseListener() {

    @Override
    public void mouseDoubleClick(MouseEvent e) {
    }

    @Override
    public void mouseDown(MouseEvent e) {
    }

    @Override
    public void mouseUp(MouseEvent e) {
        // Do the things
    }

});

대신 MouseAdapter를 사용할 수 있습니다.

public abstract class MouseAdapter implements MouseListener {
    public void mouseDoubleClick(MouseEvent e) { }
    public void mouseDown(MouseEvent e) { }
    public void mouseUp(MouseEvent e) { }
}

비어있는 기본 구현을 제공함으로써 어댑터에서 신경 쓰는 메소드 만 자유롭게 재정의 할 수 있습니다. 위의 예에서 다음을 수행합니다.

obj.addMouseListener(new MouseAdapter() {

    @Override
    public void mouseUp(MouseEvent e) {
        // Do the things
    }

});

어댑터 (UML 및 예제 상황)

더 상상할 수있는 상황에서 어댑터 패턴과 상황을 사용하기 위해 작고 간단하며 매우 구체적인 예가 여기에 제시되어 있습니다. 여기에는 코드가 없으며, UML과 예제 상황과 그 문제에 대한 설명 만있을 것입니다. 물론 UML 컨텐트는 Java와 비슷하게 작성되었습니다. (글쎄, 힌트 텍스트 "좋은 예제는 주로 코드", 나는 디자인 패턴이 너무 다른 방식으로 소개 될 정도로 추상적이라고 생각합니다.)

일반적으로 어댑터 패턴은 호환되지 않는 인터페이스가 있고 그 중 어느 것도 직접 재 작성할 수없는 상황에 적합한 솔루션입니다.

당신이 멋진 작은 피자 배달 서비스를 운영하고 있다고 상상해보십시오. 고객은 웹 사이트에서 온라인으로 주문할 수 있으며 Pizza 를 표현하고 청구서, 세금 보고서 등을 계산할 수있는 클래스 Pizza 를 사용하는 소규모 시스템을 보유하고 있습니다. 피자의 가격은 가격을 (원하는 통화의) 센트로 나타내는 단일 정수로 주어집니다.

여기에 이미지 설명을 입력하십시오.

귀하의 배달 서비스는 훌륭하게 진행되고 있지만 어느 시점에서 성장하는 고객을 더 이상 처리 할 수는 없지만 여전히 확장하고 싶습니다. 큰 온라인 메타 배달 서비스의 메뉴에 피자를 추가하기로 결정했습니다. 그들은 피자뿐만 아니라 많은 다른 식사를 제공합니다. 따라서 그들의 시스템은 추상화를 더 많이 사용하고 돈을 나타내는 클래스 MoneyAmount 와 함께 나오는 식사를 나타내는 인터페이스 IMeal 습니다.

여기에 이미지 설명을 입력하십시오.

MoneyAmount 는 쉼표 앞의 금액 (또는 임의의 통화) 하나와 쉼표 뒤의 0에서 99까지의 센트 금액에 대한 입력으로 두 개의 정수로 구성됩니다.

여기에 이미지 설명을 입력하십시오.

Pizza 의 가격이 총 가격을 센트 (> 99)로 나타내는 단일 정수이기 때문에 IMeal 과 호환되지 않습니다. 이것은 어댑터 패턴이 작동되는 지점입니다. 자신의 시스템을 변경하거나 새로운 시스템을 작성하는 데 너무 많은 노력이 들며 호환되지 않는 인터페이스를 구현해야하는 경우 어댑터 패턴을 적용 할 수 있습니다.

패턴을 적용하는 방법에는 클래스 어댑터와 객체 어댑터의 두 가지가 있습니다.

둘 다 공통적으로 어댑터 ( PizzaAdapter )가 새로운 인터페이스와 적응 자 (이 예에서는 Pizza 사이의 일종의 변환기로 작동한다는 것을 공통적으로 가지고 있습니다. 어댑터는 새로운 인터페이스 ( IMeal )를 구현 한 다음 Pizza 를 상속 받고 자체 가격을 하나의 정수에서 2 (클래스 어댑터)로 변환합니다.

여기에 이미지 설명을 입력하십시오.

또는 Pizza 유형의 객체를 속성으로 가지며 그 값 (객체 어댑터)을 변환합니다.

여기에 이미지 설명을 입력하십시오.

어댑터 패턴을 적용하면 호환되지 않는 인터페이스간에 "변환"할 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow