Реализация шаблона адаптера класса в Java - PullRequest
10 голосов
/ 10 июня 2011

Читая шаблон адаптера класса в Шаблоны проектирования Head First , я наткнулся на это предложение:

адаптер класса ... потому что для его реализации требуется множественное наследование, что невозможно в Java

Просто чтобы поэкспериментировать, я попробовал следующее:

interface MyNeededInterface{
    public void operationOne(MyNeededInterface other);
    public MyNeededInterface operationTwo();
}

public class ThirdPartyLibraryClass{
    public void thirdPartyOp();
}

Предположим, я создаю:

class ThirdPartyWrapper extends ThirdPartyLibraryClass implements MyNeededInterface{

    @Override
    public void operationOne(ThirdPartyWrapper other){
        this.thirdPartyOp();
        dosomeExtra();
    }
    @Override
    public ThirdPartyWrapper operationTwo(){
        int somevalue = doSomeThingElse();
        return new ThirdPartyWrapper(somevalue);
    }
}

В своем коде я могу использовать:

MyNeededInterface myclass = createThirdPartyWrapper();
myclass.operationOne(someobj);
...

Разве это не шаблон Class Adapter?

Ответы [ 5 ]

11 голосов
/ 10 июня 2011

Шаблон адаптера класса невозможен в Java, потому что вы не можете расширять несколько классов. Поэтому вам придется использовать шаблон адаптера, который использует композицию, а не наследование.

Пример шаблона адаптера через композицию можно найти ниже:

interface Duck
{
    public void quack();
}

class BlackDuck implements Duck
{
   public void quack() { }
}

class Turkey
{
    public void gobble() { }
}

class TurkeyAdapter implements Duck
{
    private Turkey t;

    public TurkeyAdapter(Turkey t)
    {
        this.t = t;
    }

    public void quack()
    {
        // A turkey is not a duck but, act like one
        t.gobble();
    }
}

Теперь вы можете передать Turkey методу, который ожидает Duck через TurkeyAdapter.

class DuckCatcher
{
    public void catch(Duck duck) { }
}

Используя шаблон адаптера, DuckCatcher теперь также может перехватывать Turkey(Adapter) s и Duck s.

5 голосов
/ 10 июня 2011

Да, вы можете создать адаптер класса с интерфейсом, если вы используете только один адаптер.При множественном наследовании вы можете взять два или более адаптера и объединить их в единый интерфейс.

5 голосов
/ 10 июня 2011

Полный текст в заголовке: класс шаблон адаптера невозможен в Java только потому, что Java не обеспечивает множественное наследование .

На своей диаграмме они показывают, что подклассы Adapter class оба Target и Adaptee. Ваш пример (близко к) шаблон адаптера объекта. Разница в том, что вы реализуете Target в своем классе адаптера, а не просто создаете подклассы цели (MyNeededInterface в вашем примере)

3 голосов
/ 04 сентября 2016

GoF (Gang of Four) рассказывает нам о двух основных видах адаптеров:

A. Адаптеры класса. Обычно они используют множественное наследование для адаптации одного интерфейса к другому. (Но мы должны помнить, что в Java множественное наследование через классы не поддерживается (по уважительной причине :)). Нам нужны интерфейсы для реализации концепции множественного наследования.)

B. Объектные адаптеры. Они зависят от составов объекта.

Чтобы проиллюстрировать понятия, я приведу простой пример: (источник: книга Java Design Patterns)

interface IntegerValue 
{
    public int getInteger();
}

class IntegerValue implements IntegerValue
{
    @Override
    public int getInteger() 
    {
        return 5;
    }
}
// Adapter using interface
class ClassAdapter extends IntegerValue
{
    //Incrementing by 2
    public int getInteger()
    {
        return 2 + super.getInteger();
    }
}

// Adapter using composition
class ObjectAdapter
{
    private IIntegerValue myInt;

    public ObjectAdapter(IIntegerValue myInt)
    {
        this.myInt=myInt;
    }

    //Incrementing by 2
    public int getInteger()
    {
        return 2+this.myInt.getInteger();
    }
}

class ClassAndObjectAdapter
{
    public static void main(String args[])
    {
        System.out.println("Class and Object Adapter Demo");
        ClassAdapter ca1=new ClassAdapter();
        System.out.println("Class Adapter is returning :"+ca1.getInteger());
        ClassAdapter ca2=new ClassAdapter();
        ObjectAdapter oa=new ObjectAdapter(new IntegerValue());
        System.out.println("Object Adapter is returning :"+oa.getInteger());
    }
}

Выход на консоль:

Демонстрация адаптера класса и объекта
Адаптер класса возвращается: 7
Адаптер объекта возвращается: 7

0 голосов
/ 15 февраля 2016

Адаптеры классов возможны в Java с использованием одного наследования.В качестве примера из шаблона проектирования для макетов , предположим, что мы должны адаптировать флажки AWT для использования вместе с флажками Swing, для этого мы можем написать адаптер класса.

Код пользовательского интерфейса в SwingЧтобы определить, установлен ли флажок, выполняется метод isSelected.Но флажки AWT не поддерживают isSelected (), вместо них используется getState ().

Таким образом, мы можем написать адаптер, чтобы обернуть флажок SWT и адаптировать getState () к isSelected ()

  public class CheckboxAdapter extends Checkbox
  { 

      public CheckboxAdapter(String n) 
      {
         super(n);
      }

      public boolean isSelected()
      {
         return getState();
      }
  }

Теперь мы можем работать с адаптированными флажками AWT, как если бы мы использовали стандартные флажки Swing, когда дело касается метода isSelected.

  public void itemStateChanged(ItemEvent e)
  {
      String outString = new String("Selected: ");

      for(int loopIndex = 0; loopIndex 
         <= checks.length - 1; loopIndex++){
           if(checks[loopIndex].isSelected()) {
              outString += " checkbox " + loopIndex;
           }
       }
      text.setText(outString);
   }

РЕДАКТИРОВАТЬ: Истинный адаптер класса невозможен в Java, если ониесли бы мы могли наследовать от нескольких классов, которые мы хотим имитировать в классе адаптера.

Также см. http://www.journaldev.com/1487/adapter-design-pattern-in-java-example-tutorial для двух примеров в Java, использующих адаптер класса и адаптер объекта, для достижения одного и того же результата.

...