어댑터-어댑터 패턴의 실제 예 [닫힘]


84

팀 에 어댑터 패턴 사용을 시연하고 싶습니다 . 온라인에서 많은 책과 기사를 읽었습니다. 모두가 개념 (모양, 메모리 카드, 전자 어댑터 등)을 이해하는 데 유용한 예를 인용하고 있지만 실제 사례 연구는 없습니다.

Adapter Pattern의 사례 연구를 공유해 주시겠습니까?

추신 나는 stackoverflow에서 기존 질문을 검색하려고 시도했지만 답을 찾지 못 했으므로 새 질문으로 게시했습니다. 이미 이에 대한 답이 있다는 것을 알고 있다면 리디렉션하십시오.


4
데모를 원한다면 글쎄요. 당신은 당신의 환경에 준비된 예제를 가지고 있어야합니다. 그렇지 않으면 왜 데모를 원하십니까?
Tony Hopkinson 2012-06-18

1
여기에 몇 가지 예가 있습니다. stackoverflow.com/questions/1673841/…
r4.

1
@TonyHopkinson 목표는 사람들이이 디자인 패턴을 실제 사례로 인식하도록하는 것입니다.
AksharRoop

10
@AksharRoop. 디자인 패턴은 문제를 찾는 솔루션이 아니라 문제에 대한 솔루션을 의미합니다. 가장 좋은 예는 자신의 "세계"에있는 것입니다.
Tony Hopkinson

1
@TonyHopkinson 여기서 잘못된 용어를 사용한 것 같습니다. 그러나 제가 의미하는 것은이 패턴의 개념을 좋은 예로 설명하는 것입니다. 나는 내 자신의 시스템에서 하나 ... 찾아야한다 동의
AksharRoop

답변:


77

어댑터의 많은 예는 사소하거나 비현실적입니다 ( Rectangle vs. LegacyRectangle , Ratchet vs. Socket , SquarePeg vs RoundPeg , Duck vs. Turkey ). 더 나쁜 것은 많은 사람들이 다른 어댑터에 대해 여러 어댑터를 표시하지 않는다는 것입니다 ( 누군가가 어댑터 패턴의 예로 Java의 Arrays.asList를 인용했습니다 ). 한 클래스 의 인터페이스 만 다른 클래스 와 함께 작동하도록 조정하는 것은 GoF 어댑터 패턴의 약한 예인 것 같습니다. 이 패턴은 상속과 다형성을 사용하므로 서로 다른 어댑터에 대한 여러 어댑터 구현 을 보여주는 좋은 예를 기대할 수 있습니다.

좋은 예 내가 찾은이의 제 26 장에 객체 지향 분석 및 설계 및 반복 개발 (제 3 판)에 대한 소개 : UML과 패턴을 적용 . 다음 이미지는 책의 FTP 사이트에 제공된 강사 자료에서 가져온 것입니다.

첫 번째는 애플리케이션이 기능적으로 유사하지만 (예 : 세금 계산기, 회계 모듈, 신용 인증 서비스 등) 서로 다른 API를 갖는 여러 구현 (어댑티브)을 어떻게 사용할 수 있는지 보여줍니다. 세금 계산, 판매 후, 신용 카드 요청 승인 등의 다양한 가능한 방법을 처리하기 위해 도메인 계층 코드를 하드 코딩하지 않으려 고합니다. 이러한 모듈은 모두 다를 수 있으며 수정할 수없는 외부 모듈입니다. 암호. 어댑터를 사용하면 어댑터에서 하드 코딩을 수행 할 수 있지만 도메인 계층 코드는 항상 동일한 인터페이스 (IWhateverAdapter 인터페이스)를 사용합니다.

그림 26.1

위의 그림에서는 실제 적응자를 볼 수 없습니다. 그러나 다음 그림은 postSale(...)IAccountingAdapter 인터페이스에서 다형성 호출을 수행 하여 SOAP를 통해 SAP 시스템에 판매를 게시 하는 방법을 보여줍니다 .

그림 26.2


세션을 사용하여이 예 (구현이 아니지만 완전히 바로, 나는 정적을 사용하여, 생각)도 꽤 좋은 : community.sitepoint.com/t/phpunit-testing-cookies-and-sessions/...
알레한드로 모레노


50

프랑스 사람을 평범한 사람으로 바꾸는 방법 ...

 public interface IPerson
    {
        string Name { get; set; }
    }

    public interface IFrenchPerson
    {
        string Nom { get; set; }
    }

    public class Person : IPerson
    {
        public string Name { get; set; }
    }

    public class FrenchPerson : IFrenchPerson
    {
        public string Nom { get; set; }
    }

    public class PersonService
    {
        public void PrintName(IPerson person)
        {
            Debug.Write(person.Name);
        }
    }

    public class FrenchPersonAdapter : IPerson
    {
        private readonly IFrenchPerson frenchPerson;

        public FrenchPersonAdapter(IFrenchPerson frenchPerson)
        {
            this.frenchPerson = frenchPerson;
        }

        public string Name 
        {
            get { return frenchPerson.Nom; }
            set { frenchPerson.Nom = value; }
        }
    } 

    var service = new PersonService();
    var person = new Person();
    var frenchPerson = new FrenchPerson();

    service.PrintName(person);
    service.PrintName(new FrenchPersonAdapter(frenchPerson));

19
나는 프랑스 사람이고 당신이 나를 진짜 사람이라고 생각하지 않는다는 모욕감을 느낍니다. (JK)
ZeroUltimax

13
@ZeroUltimax 저는이 코드가 퀘벡에서 컴파일되지 않을 것이라고 확신합니다.
Fuhrmanator 2017-10-20

어댑터에 대한 지식이없는 코더라면 문제를 쉽게 해결했을 것입니다. 어댑터 이론에 대한 지식이 시간을 절약하거나 솔루션을 개선하는 데 어떻게 도움이됩니까? 메서드를 사용하는 대신 특수 클래스를 사용하는 것이 궁극적 인 요점입니까?
Rowan Gontier

인터페이스를 제어하지 않고 클래스 중 하나를 타사 라이브러리에 맞게 조정해야하는 경우 어떻게해야합니까? 이 답변의 범위를 벗어난 다른 좋은 이유가 많이 있습니다.
CountZero

3
이것은 내가 본 어댑터 패턴을 사용하는 방법에 대한 가장 재미있는 단일 예이며 아마도 가장 접근하기 쉬운 예 중 하나입니다.
Mass Dot Net

42

인터페이스를 다른 인터페이스로 변환합니다.

어댑터 패턴의 실제 예

전원을 연결하기 위해 전 세계에 서로 다른 인터페이스가 있습니다. Adapter를 사용하면 현명하게 쉽게 연결할 수 있습니다.

여기에 이미지 설명 입력


여기에 대응하는 코드는 다음과 같습니다 codeproject.com/Tips/595716/Adapter-Design-Pattern-in-Cplusplus
래 가브 Navada


13

여기서 변환 시뮬레이트 예이다 analog datadigit data.

부동 숫자 데이터를 이진 데이터로 변환하는 어댑터를 제공합니다. 실제 환경에서는 유용하지 않을 수 있으며 어댑터 패턴의 개념을 설명하는 데 도움이됩니다.


암호

AnalogSignal.java

package eric.designpattern.adapter;

public interface AnalogSignal {
    float[] getAnalog();

    void setAnalog(float[] analogData);

    void printAnalog();
}

DigitSignal.java

package eric.designpattern.adapter;

public interface DigitSignal {
    byte[] getDigit();

    void setDigit(byte[] digitData);

    void printDigit();
}

FloatAnalogSignal.java

package eric.designpattern.adapter;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FloatAnalogSignal implements AnalogSignal {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private float[] data;

    public FloatAnalogSignal(float[] data) {
        this.data = data;
    }

    @Override
    public float[] getAnalog() {
        return data;
    }

    @Override
    public void setAnalog(float[] analogData) {
        this.data = analogData;
    }

    @Override
    public void printAnalog() {
        logger.info("{}", Arrays.toString(getAnalog()));
    }
}

BinDigitSignal.java

package eric.designpattern.adapter;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BinDigitSignal implements DigitSignal {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private byte[] data;

    public BinDigitSignal(byte[] data) {
        this.data = data;
    }

    @Override
    public byte[] getDigit() {
        return data;
    }

    @Override
    public void setDigit(byte[] digitData) {
        this.data = digitData;
    }

    @Override
    public void printDigit() {
        logger.info("{}", Arrays.toString(getDigit()));
    }
}

AnalogToDigitAdapter.java

package eric.designpattern.adapter;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * Adapter - convert analog data to digit data.
 * </p>
 * 
 * @author eric
 * @date Mar 8, 2016 1:07:00 PM
 */
public class AnalogToDigitAdapter implements DigitSignal {
    public static final float DEFAULT_THRESHOLD_FLOAT_TO_BIN = 1.0f; // default threshold,
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private AnalogSignal analogSignal;
    private byte[] digitData;
    private float threshold;
    private boolean cached;

    public AnalogToDigitAdapter(AnalogSignal analogSignal) {
        this(analogSignal, DEFAULT_THRESHOLD_FLOAT_TO_BIN);
    }

    public AnalogToDigitAdapter(AnalogSignal analogSignal, float threshold) {
        this.analogSignal = analogSignal;
        this.threshold = threshold;
        this.cached = false;
    }

    @Override
    public synchronized byte[] getDigit() {
        if (!cached) {
            float[] analogData = analogSignal.getAnalog();
            int len = analogData.length;
            digitData = new byte[len];

            for (int i = 0; i < len; i++) {
                digitData[i] = floatToByte(analogData[i]);
            }
        }

        return digitData;
    }

    // not supported, should set the inner analog data instead,
    @Override
    public void setDigit(byte[] digitData) {
        throw new UnsupportedOperationException();
    }

    public synchronized void setAnalogData(float[] analogData) {
        invalidCache();
        this.analogSignal.setAnalog(analogData);
    }

    public synchronized void invalidCache() {
        cached = false;
        digitData = null;
    }

    @Override
    public void printDigit() {
        logger.info("{}", Arrays.toString(getDigit()));
    }

    // float -> byte convert,
    private byte floatToByte(float f) {
        return (byte) (f >= threshold ? 1 : 0);
    }
}

코드-테스트 케이스

AdapterTest.java

package eric.designpattern.adapter.test;

import java.util.Arrays;

import junit.framework.TestCase;

import org.junit.Test;

import eric.designpattern.adapter.AnalogSignal;
import eric.designpattern.adapter.AnalogToDigitAdapter;
import eric.designpattern.adapter.BinDigitSignal;
import eric.designpattern.adapter.DigitSignal;
import eric.designpattern.adapter.FloatAnalogSignal;

public class AdapterTest extends TestCase {
    private float[] analogData = { 0.2f, 1.4f, 3.12f, 0.9f };
    private byte[] binData = { 0, 1, 1, 0 };
    private float[] analogData2 = { 1.2f, 1.4f, 0.12f, 0.9f };

    @Test
    public void testAdapter() {
        AnalogSignal analogSignal = new FloatAnalogSignal(analogData);
        analogSignal.printAnalog();

        DigitSignal digitSignal = new BinDigitSignal(binData);
        digitSignal.printDigit();

        // adapter
        AnalogToDigitAdapter adAdapter = new AnalogToDigitAdapter(analogSignal);
        adAdapter.printDigit();
        assertTrue(Arrays.equals(digitSignal.getDigit(), adAdapter.getDigit()));

        adAdapter.setAnalogData(analogData2);
        adAdapter.printDigit();
        assertFalse(Arrays.equals(digitSignal.getDigit(), adAdapter.getDigit()));
    }
}

종속성-Maven을 통해

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.13</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.13</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>

테스트 방법

단위 테스트를 실행하십시오.


7

어댑터 패턴은 호환되지 않는 두 인터페이스 사이의 다리 역할을합니다. 이 패턴에는 두 개의 독립적이거나 호환되지 않는 인터페이스 간의 통신을 담당하는 어댑터라는 단일 클래스가 포함됩니다.

실제 사례로는 언어 번역기 나 모바일 충전기가 있습니다. 이 유튜브 비디오에서 더 여기 :

Youtube-어댑터 디자인 패턴 : 소개


3

동작이 유사한 다른 인터페이스를 처리해야 할 때 어댑터 디자인 패턴을 사용할 수 있습니다 (일반적으로 동작이 비슷하지만 메서드가 다른 클래스를 의미 함). 예를 들어 삼성 TV에 연결하는 클래스와 소니 TV에 연결하는 다른 클래스가 있습니다. 메뉴 열기, 재생 시작, 네트워크 연결 등과 같은 일반적인 동작을 공유하지만 각 라이브러리는 다른 방식으로 구현됩니다 (다른 메서드 이름 및 서명 사용). 이러한 다른 공급 업체별 구현은 UML 다이어그램에서 Adaptee 라고 합니다.

따라서 코드 ( UML 다이어그램 에서는 Client 라고 함 )에서 각 공급 업체 (또는 Adaptee ) 의 메서드 호출을 하드 코딩하는 대신 일반 인터페이스 ( UML 다이어그램 에서는 Target 이라고 함 )를 만들어 이러한 유사한 동작을 래핑하고 작업 할 수 있습니다. 한 가지 유형의 개체 만 사용합니다.

어댑터는 다음 구현할 대상을 받는 사람의 메소드 호출 위임 인터페이스 Adaptees 에 전달되는 어댑터 생성자를 통해입니다.

Java 코드로이를 실현하기 위해 위에서 언급 한 것과 동일한 예제를 어댑터를 사용하여 여러 스마트 TV 인터페이스를 처리하는 매우 간단한 프로젝트를 작성했습니다. 코드는 작고 잘 문서화되어 있으며 설명이 필요하므로 실제 구현이 어떻게 보이는지 자세히 살펴보십시오.

코드를 다운로드하고 Eclipse (또는 선호하는 IDE)에 Maven 프로젝트로 가져 오면됩니다. org.example.Main.java를 실행하여 코드를 실행할 수 있습니다 . 여기서 중요한 것은 패턴을 디자인하기 위해 클래스와 인터페이스를 함께 조합하는 방법을 이해하는 것입니다. 또한 일부 가짜를 만들어 Adaptees 패키지에 com.thirdparty.libs을 . 도움이 되었기를 바랍니다.

https://github.com/Dannemann/java-design-patterns


2

하나의 실제 예는 Qt-Dbus입니다.

qt-dbus에는 제공된 xml 파일에서 어댑터 및 인터페이스 코드를 생성하는 유틸리티가 있습니다. 이를위한 단계는 다음과 같습니다.

 1. Create the xml file - this xml file should have the interfaces 
that can be viewed by the qdbus-view in the system either on 
the system or session bus.

    2.With the utility - qdbusxml2cpp , you generate the interface adaptor code. 
This interface adaptor does the demarshalling of the data that is 
received from the client. After demarshalling, it invokes the 
user defined - custom methods ( we can say as adaptee).

    3. At the client side, we generate the interface from the xml file. 
This interface is invoked by the client. The interface does the 
marshalling of the data and invokes the adaptor interface. As told 
in the point number 2, the adaptor interface does the demarshalling 
and calls the adaptee - user defined methods.

여기에서 Qt-Dbus의 전체 예를 볼 수 있습니다.

http://www.tune2wizard.com/linux-qt-signals-and-slots-qt-d-bus/


2

여기에서 주입 공격에 대한 방어로 사용되는 어댑터 패턴의 PHP 구현을 찾을 수 있습니다.

http://www.php5dp.com/category/design-patterns/adapter-composition/

어댑터 패턴의 흥미로운 측면 중 하나는 다중 상속에 의존하는 클래스 어댑터와 컴포지션에 의존하는 객체 어댑터의 두 가지 특징이 있다는 것입니다. 위의 예는 구성에 의존합니다.


php5dp.com/category/design-patterns/adapter-composition 링크 가 더 이상 작동하지 않습니다
FantomX1

2

어댑터 디자인 패턴은 한 클래스의 인터페이스를 클라이언트가 기대하는 인터페이스로 변환하는 데 도움이됩니다.

예 : 도시 이름을 입력 값으로 전달하여 날씨 (섭씨)를 반환하는 서비스가 있습니다. 이제 고객이 우편 번호를 입력으로 전달하고 그 대가로 도시의 온도를 예상한다고 가정합니다. 이를 위해서는 어댑터가 필요합니다.

public interface IWetherFinder {
    public double getTemperature(String cityName);
}

class WeatherFinder implements IWetherFinder{
   @Override
   public double getTemperature(String cityName){
     return 40;
   }
}

interface IWeatherFinderClient
{
   public double getTemperature(String zipcode);
}  

public class WeatherAdapter implements IWeatherFinderClient {

    @Override
    public double getTemperature(String zipcode) {

        //method to get cityname by zipcode 
        String cityName = getCityName(zipcode);

        //invoke actual service
        IWetherFinder wetherFinder = new WeatherFinder();
        return wetherFinder.getTemperature(cityName);
    }

    private String getCityName(String zipCode) {
        return "Banaglore";
    }
}

0

실제 예는 애플리케이션에서 문서를보고하는 것입니다. 여기와 같이 간단한 코드.

내가 생각하는 어댑터는 프로그래밍 구조에 매우 유용합니다.

class WordAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Word");
    }
}

class ExcellAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Excel");
    }
}


class ReportAdapter implements IReport{
    WordAdaptee wordAdaptee=new WordAdaptee();
    @Override
    public void report(String s) {
        wordAdaptee.report(s);
    }
}

interface IReport {
    public void report(String s);
}

public class Main {
    public static void main(String[] args) {

        //create the interface that client wants
        IReport iReport=new ReportAdapter();

        //we want to write a report both from excel and world
        iReport.report("Trial report1 with one adaptee");  //we can directly write the report if one adaptee is avaliable 

        //assume there are N adaptees so it is like in our example
        IReport[] iReport2={new ExcellAdaptee(),new WordAdaptee()};

        //here we can use Polymorphism here  
        for (int i = 0; i < iReport2.length; i++) {
            iReport2[i].report("Trial report 2");
        }
    }
}

결과는 다음과 같습니다.

Trial report1 with one adaptee Word
Trial report 2 Excel
Trial report 2 Word

1
이것은 실제로 프록시입니다. 어댑터와 어댑터는 인터페이스가 다릅니다. 동일한 인터페이스를 구현하지 않습니다. 그것이 프록시가하는 일입니다.
dvallejo

이것은 어댑터 패턴이 아닙니다. 어댑터 패턴은 어댑터가 구현하지 않는 대상 인터페이스를 구현하는 데 사용됩니다.
FedericoG

0

변경할 수 없지만 사용해야하는 인터페이스가있는 경우 Adapter를 사용하십시오. 당신이 사무실의 새로운 사람이기 때문에 당신은 회색 머리가 당신의 규칙을 따르도록 만들 수 없습니다. 당신은 그들의 규칙에 적응해야합니다. 다음은 사용자 인터페이스가 주어진 곳에서 작업 한 실제 프로젝트의 실제 예제입니다.

파일의 모든 줄을 List 데이터 구조로 읽어 그리드에 표시하는 애플리케이션이 있습니다 (기본 데이터 저장소 인터페이스 IDataStore라고하겠습니다). 사용자는 "첫 페이지", "이전 페이지", "다음 페이지", "마지막 페이지"버튼을 클릭하여 이러한 데이터를 탐색 할 수 있습니다. 모든 것이 잘 작동합니다.

이제 애플리케이션은 너무 커서 메모리로 읽을 수없는 프로덕션 로그와 함께 사용해야하지만 사용자는 계속 탐색해야합니다! 한 가지 해결책은 첫 페이지, 다음, 이전 및 마지막 페이지를 저장하는 캐시를 구현하는 것입니다. 우리가 원하는 것은 사용자가 "다음 페이지"를 클릭하면 캐시에서 페이지를 반환하고 캐시를 업데이트하는 것입니다. 마지막 페이지를 클릭하면 캐시에서 마지막 페이지를 반환합니다. 백그라운드에는 모든 마법을 수행하는 파일 스트림이 있습니다. 이렇게하면 전체 파일이 아니라 메모리에 4 페이지 만 있습니다.

어댑터를 사용하여 사용자가 알지 못하는 사이에이 새로운 캐시 기능을 애플리케이션에 추가 할 수 있습니다. 현재 IDataStore를 확장하고 CacheDataStore라고합니다. 로드 할 파일이 크면 CacheDataStore를 사용합니다. 첫 페이지, 다음 페이지, 이전 페이지 및 마지막 페이지를 요청하면 정보가 캐시로 전달됩니다.

그리고 누가 알겠습니까? 내일 상사는 데이터베이스 테이블에서 파일을 읽기 시작하려고합니다. 캐시에 대해 수행 한 것처럼 IDataStore를 SQLDataStore로 확장하고 백그라운드에서 연결을 설정하기 만하면됩니다. 다음 페이지를 클릭하면 데이터베이스에서 다음 200 개 행을 가져 오는 데 필요한 SQL 쿼리를 생성합니다.

기본적으로 응용 프로그램의 원래 인터페이스는 변경되지 않았습니다. 레거시 인터페이스를 유지하면서 현대적이고 멋진 기능을 적용하여 작업했습니다.


이해가 안 되나요? 방금 기존 인터페이스를 사용하고 메서드를 구현 한 것 같습니까? 적응해야하는 다른 인터페이스와 어댑터 클래스는 어디에 있습니까?
berimbolo

@berimbolo 위의 예에서 어댑터 패턴에 대해 명확하게 이야기하지 않으므로 혼란이 유효합니다.
rahil008

0

@Justice o의 예제는 어댑터 패턴에 대해 명확하게 이야기하지 않습니다. 그의 대답 확장-우리는 소비자 코드가 사용하는 기존 인터페이스 IDataStore가 있으며 변경할 수 없습니다. 이제 구현하려는 작업을 수행하는 XYZ 라이브러리의 멋진 새 클래스를 사용하도록 요청 받았지만 해당 클래스를 변경하여 IDataStore를 확장 할 수는 없습니다. 우리 소비자 코드가 기대하는 인터페이스, 즉 IDataStore를 구현하는 새로운 클래스 ADAPTER를 만들고, 우리가 가지고 있어야하는 기능이있는 라이브러리의 클래스 인 ADAPTEE를 ADAPTER의 멤버로 사용하여 우리가 원하는 것을 얻을 수 있습니다.



0

Yii 프레임 워크의 예는 다음과 같습니다. Yii는 인터페이스 ICache를 사용하여 내부적으로 캐시를 사용합니다. https://www.yiiframework.com/doc/api/1.1/ICache

서명은 다음과 같습니다.-

abstract public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency $dependency=NULL)
abstract public mixed get(string $id)

Yii 서비스 구성 요소 (서비스 로케이터) 구성 https : / 에서이 서비스를 정의 하여 Yii 프로젝트 내에서 Symfony 캐시 라이브러리 https://packagist.org/packages/symfony/cache 를 캐시 인터페이스와 함께 사용하고 싶다고 가정 해 보겠습니다 . /github.com/symfony/cache-contracts/blob/master/CacheInterface.php

    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null);

Symfony는 두 번째 호출 가능 매개 변수를 제공 할 때 get 메소드를 setter로도 사용하기 때문에, symfony 캐시에는 get 메소드 만있는 인터페이스가 있고 get 메소드에 대해 set 메소드와 다른 서명이 누락되어 있습니다.

Yii 코어가 내부적으로이 Yii 캐시 / 인터페이스를 사용하기 때문에, 장소에서 불가능하지는 않더라도 해당 인터페이스에 대한 호출을 다시 작성하기가 어렵습니다 (Yii / YiiBase 확장).

Plus Symfony 캐시는 우리 클래스도 아니므로 Yii 캐시 인터페이스에 맞게 인터페이스를 다시 작성할 수 없습니다.

이제 구조 할 어댑터 패턴이 있습니다. 매핑을 작성합니다 = Yii 캐시 인터페이스 호출을 Symfony 캐시 인터페이스에 매핑하는 중간 어댑터

이렇게 보일까요

    class YiiToSymfonyCacheAdapter implements \Yii\system\caching\ICache
    {
        private \Symfony\Contracts\Cache\CacheInterface $symfonyCache;

        public function __construct(\Symfony\Contracts\Cache\CacheInterface $symfonyCache)
        {
            $this->symfonyCache = $symfonyCache;
        }

      
      public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency 
       $dependency=NULL) 
      {

          // https://symfony.com/doc/current/cache.html
          return $this->symfonyCache->get(
              $id, 
              function($item) { 
              // some logic .. 
               return $value; 
              }
          );

//          https://github.com/symfony/cache/blob/master/Adapter/MemcachedAdapter.php
// if a class could be called statically, the adapter could call statically also eg. like this
//          return \Symfony\Component\Cache\Adapter\MemcacheAdapter::get(
//              $id, 
//              function($item) { 
//              // some logic .. 
//               return $value; 
//              }
          );
       }

       public mixed get(string $id) 
       {
           // https://github.com/symfony/cache/blob/master/Adapter/FilesystemAdapter.php 
           // if a class could be called statically, the adapter could call statically also eg. like this
           // \Symfony\Component\Cache\Adapter\FileSystemAdapter::get($id)
           return $this->symfonyCache->get($id) 
       }
    } 


-1

다음은 어댑터 구현의 예입니다.

interface NokiaInterface {
    chargementNokia(x:boolean):void
}


class SamsungAdapter implements NokiaInterface {
//nokia chargement adapted to samsung
    chargementNokia(x:boolean){
        const old= new SamsungCharger();
        let y:number = x ? 20 : 1;
        old.charge(y);
      }
}


class SamsungCharger {
      charge(x:number){
            console.log("chrgement x ==>", x);
      }
}


function main() {
      //charge samsung with nokia charger
      const adapter = new SamsungAdapter();
      adapter.chargementNokia(true);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.