Files
Leonardo Lisanti 01aba886e9 translation: translation of acyclic visitor pattern to Italian (#2699)
* translation: translation of acyclic visitor pattern to Italian

* translation: translation of acyclic visitor pattern to Italian - added the pre-existing lines to Applicability

---------

Co-authored-by: Leonardo Lisanti <leonardo_lisanti@epam.com>
2023-10-26 21:47:43 +03:00
..

title, category, language, tag
title category language tag
Acyclic Visitor Behavioral it
Extensibility

Intento

Permette di aggiungere nuove funzioni alle gerarchie di classi esistenti senza influire su tali gerarchie e senza creare i cicli di dipendenza problematici che sono intrinseci al pattern Visitor dei GoF.

Spiegazione

Esempio del mondo reale

Abbiamo una gerarchia di classi di modem. I modem in questa gerarchia devono essere visitati da un algoritmo esterno basato su criteri di filtraggio (ad esempio, se si tratta di un modem compatibile con Unix o DOS).

In parole semplici

L'Acyclic Visitor consente di aggiungere funzioni alle gerarchie di classi esistenti senza modificarle.

WikiWikiWeb dice

Il pattern Acyclic Visitor consente di aggiungere nuove funzioni alle gerarchie di classi esistenti senza influire su tali gerarchie e senza creare i cicli di dipendenza che sono intrinseci al pattern Visitor dei Gang of Four. (Testo tradotto dalla voce Acyclic Visitor da WikiWikiWeb in lingua inglese).

Esempio di codice

Ecco la gerarchia delle classi Modem.

public abstract class Modem {
  public abstract void accept(ModemVisitor modemVisitor);
}

public class Zoom extends Modem {
  ...
  @Override
  public void accept(ModemVisitor modemVisitor) {
    if (modemVisitor instanceof ZoomVisitor) {
      ((ZoomVisitor) modemVisitor).visit(this);
    } else {
      LOGGER.info("Only ZoomVisitor is allowed to visit Zoom modem");
    }
  }
}

public class Hayes extends Modem {
  ...
  @Override
  public void accept(ModemVisitor modemVisitor) {
    if (modemVisitor instanceof HayesVisitor) {
      ((HayesVisitor) modemVisitor).visit(this);
    } else {
      LOGGER.info("Only HayesVisitor is allowed to visit Hayes modem");
    }
  }
}

Successivamente introduciamo la gerarchia delle classi ModemVisitor.

public interface ModemVisitor {
}

public interface HayesVisitor extends ModemVisitor {
  void visit(Hayes hayes);
}

public interface ZoomVisitor extends ModemVisitor {
  void visit(Zoom zoom);
}

public interface AllModemVisitor extends ZoomVisitor, HayesVisitor {
}

public class ConfigureForDosVisitor implements AllModemVisitor {
  ...
  @Override
  public void visit(Hayes hayes) {
    LOGGER.info(hayes + " used with Dos configurator.");
  }
  @Override
  public void visit(Zoom zoom) {
    LOGGER.info(zoom + " used with Dos configurator.");
  }
}

public class ConfigureForUnixVisitor implements ZoomVisitor {
  ...
  @Override
  public void visit(Zoom zoom) {
    LOGGER.info(zoom + " used with Unix configurator.");
  }
}

Infine, ecco i visitatori in azione.

    var conUnix = new ConfigureForUnixVisitor();
    var conDos = new ConfigureForDosVisitor();
    var zoom = new Zoom();
    var hayes = new Hayes();
    hayes.accept(conDos);
    zoom.accept(conDos);
    hayes.accept(conUnix);
    zoom.accept(conUnix);   

Output del programma:

    // Hayes modem used with Dos configurator.
    // Zoom modem used with Dos configurator.
    // Only HayesVisitor is allowed to visit Hayes modem
    // Zoom modem used with Unix configurator.

Diagramma delle classi

alt text

Applicabilità

Questo pattern può essere utilizzato nei seguenti casi:

  • Quando è necessario aggiungere una nuova funzione a una gerarchia esistente senza la necessità di modificarla o influenzarla.
  • Quando ci sono funzioni che operano su una gerarchia, ma che non appartengono alla gerarchia stessa, ad esempio, il problema di ConfigureForDOS / ConfigureForUnix / ConfigureForX.
  • Quando è necessario eseguire operazioni molto diverse su un oggetto a seconda del suo tipo.
  • Quando la gerarchia delle classi visitate sarà frequentemente estesa con nuovi derivati dalla classe Element.
  • Quando la ricompilazione, il relinking, il ritestare o la ridistribuzione dei derivati da Element è molto costoso.

Tutorial

Conseguenze

Aspetti positivi:

  • Assenza di cicli di dipendenza tra le gerarchie di classi.
  • Non è necessario ricompilare tutti i visitatori se se ne aggiunge uno nuovo.
  • Non causa errori di compilazione nei visitatori esistenti se la gerarchia delle classi ha un nuovo membro.

Aspetti negativi:

  • Viola il Principio di sostituzione di Liskov mostrando di poter accettare tutti i visitatori ma essendo solo interessato a visitatori specifici.
  • Deve essere creata una gerarchia parallela di visitatori per tutti i membri della gerarchia di classi visitabili.

Pattern correlati

Collegamenti esterni