Implémentation du modèle d'adaptateur de classe en Java


En lisant le modèle d'adaptateur de classe dans Head First Design Patterns , je suis tombé sur cette phrase:

Adaptateur de classe... parce que vous avez besoin de plusieurs héritages pour l'implémenter, ce qui n'est pas possible en Java

Juste pour expérimenter, j'ai essayé ce qui suit:

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

public class ThirdPartyLibraryClass{
    public void thirdPartyOp();
}

Supposons que je crée:

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);
    }
}

Dans mon code, je peux utiliser:

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

N'est-ce pas le modèle d'adaptateur de classe?

Author: blacktide, 2011-06-10

5 answers

Le modèle d'adaptateur de classe n'est pas possible en Java car vous ne pouvez pas étendre plusieurs classes. Vous devrez donc utiliser le modèle d'adaptateur qui utilise la composition plutôt que l'héritage.

Un exemple du modèle d'adaptateur à travers la composition peut être trouvé ci-dessous:

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();
    }
}

Maintenant, vous pouvez passer un Turkey une méthode qui attend un Duck par le biais de la TurkeyAdapter.

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

En utilisant l'adaptateur modèle DuckCatcher est maintenant également capable d'attraper Turkey(Adapter)s et Ducks.

 11
Author: Kevin, 2011-06-10 12:05:41

Oui, vous pouvez créer un adaptateur de classe avec une interface tant que vous n'encapsulez qu'un seul adaptee. Avec l'héritage multiple, vous pouvez prendre deux ou plusieurs adaptees et les envelopper dans une seule interface.

 5
Author: Pace, 2011-06-10 11:45:44

L'intégralité de L'histoire dans la tête est: classe adaptateur est impossible en Java, tout simplement parce que Java ne fournit pas de héritage multiple.

Dans leur diagramme, ils montrent que la classe Adapter sous-classe à la fois Target et Adaptee. Votre exemple est (proche) du modèle d'adaptateur d'objet. La différence est que vous implémentez la cible dans votre classe d'adaptateur, plutôt que de simplement sous-classer la cible (MyNeededInterface dans votre exemple)

 5
Author: Andreas_D, 2011-06-10 11:52:00

GoF (Gang of Four) nous parle de deux principaux types d'adaptateurs:

A. Adaptateurs de classe. Ils utilisent généralement l'héritage multiple pour adapter une interface à une autre. (Mais nous devons nous rappeler, en java, l'héritage multiple via les classes n'est pas pris en charge (pour une bonne raison :) ). Nous avons besoin d'interfaces pour implémenter le concept d'héritage multiple.)

B. Adaptateurs d'objet. Ils dépendent des compositions d'objets.

Pour illustrer les concepts, je vais présenter un simple exemple: (source: livre Modèles de conception Java)

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());
    }
}

Sortie console:

Démo d'adaptateur de classe et d'objet
L'adaptateur de classe est de retour: 7
L'adaptateur d'objet retourne: 7

 3
Author: timothy, 2016-09-04 16:25:04

Les adaptateurs de classe sont en quelque sorte possibles en Java en utilisant un héritage unique. À titre d'exemple de Design pattern for dummies, supposons que nous devions adapter les cases à cocher AWT pour être utilisées avec les cases à cocher Swing, nous pouvons écrire un adaptateur de classe pour cela.

Le code de l'interface utilisateur dans Swing pour déterminer si une case à cocher est cochée est effectué avec la méthode isSelected. Mais, les cases à cocher AWT ne prennent pas en charge isSelected(), elles utilisent getState() à la place.

Nous pouvons donc écrire un adaptateur pour envelopper un SWT cochez la case et adaptez getState () à isSelected ()

  public class CheckboxAdapter extends Checkbox
  { 

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

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

Maintenant, nous pouvons gérer les cases à cocher adaptées à AWT comme nous le ferions avec les cases à cocher Swing standard en ce qui concerne la méthode 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);
   }

EDIT: Les vrais adaptateurs de classe ne sont pas possibles en Java, s'ils l'étaient, nous pourrions hériter de plusieurs classes, que nous voulons imiter dans une classe d'adaptateur.

Voir aussi http://www.journaldev.com/1487/adapter-design-pattern-in-java-example-tutorial pour deux exemples en Java en utilisant Adaptateur de classe et adaptateur d'objet, pour obtenir le même résultat.

 0
Author: Saad, 2016-02-15 03:58:50