Alla ricerca di una strategia per garantire che il nome del nodo figlio rimanga univoco nella raccolta

3

Anche se sto programmando in PHP, sono aperto a rivedere i suggerimenti indipendenti dalla lingua, in quanto potrebbero indirizzarmi verso indicazioni preziose.

Per rimuovere ogni possibile confusione, sento che alcuni commenti sembrano alludere a: Page s in questa domanda non si riferiscono alle pagine web, ma alla memoria pagine per un'API simile all'elaborazione di testi e / o un foglio di lavoro.

Ho una classe Page le cui istanze possono far parte di una raccolta Pages . Questi oggetti Page devono essere denominati in modo univoco se fanno parte di una raccolta Pages , poiché devono essere identificabili univocamente con il loro nome.

Un oggetto Page non può mai appartenere a più collezioni Pages allo stesso tempo: verranno spostate o copiate (clonate).

Anche i consumatori potranno modificare il nome di singoli oggetti Page , ad esempio con 1 :

$page = new Page( 'Optional name' );
// or ($pages is a Pages collection instance)
$page = $pages->getByName( 'Page 1' );

// and then
$page->setName( 'My Page' );

Se una Page viene aggiunta a una raccolta Pages , la raccolta garantirà che il Page sia rinominato, se il suo nome è in conflitto con un altro Page nella raccolta, in questo modo:

class Pages
{
  private $objectIndex;
  private $nameIndex;

  public function __construct() {
    $this->objectIndex = new SplObjectStorage;
    $this->nameIndex = [];
  }

  public function add( Page $page ) {
    if( !$this->objectIndex->contains( $page ) ) {
      $name = $page->getName();
      if( isset( $this->nameIndex[ $name ] ) ) {
        // make name unique to this collection
        $name = $this->someLogicToMakeNameUnique( $name );
        // alter name
        $page->setName( $name );
      }
      $this->nameIndex[ $name ] = $page;
      $this->objectIndex->attach( $page, $name );
    }
  }

  public function getByName( $name ) {
    if( isset( $this->nameIndex[ $name ] ) ) {
      $this->nameIndex[ $name ];
    }

    return null;
  }
}

Sto cercando di trovare una strategia per assicurarmi che, se un Page fa parte di una raccolta e il suo nome è stato modificato, il nome viene automaticamente adattato a un nome univoco (cioè se "Page 1" già esiste, rinominalo in "Page 2" ) e anche le chiavi Pages::$nameIndex vengono correttamente aggiornate (in quanto ciò consente un recupero più veloce di Page per nome rispetto al suo ciclo Page s fino a quando un nome corrisponde).

Le strategie che ho escogitato finora sono:

  1. Passa Pages collection a Page::setParent( Pages $container ) e chiama alcuni meccanismi di verifica / igiene su $this->container in Page::setName( $name ) , prima di alterare.

  2. Emetti un rename evento da Page::setName( $name ) e fai Pages fai qualcosa come $event->preventDefault() se il nome è in conflitto e quindi Pages modifica il nome in qualcosa di unico.

L'opzione 1 sembra la più semplice / più pigra / meno intensiva del processo, ma pone la responsabilità di verificare l'unicità in un oggetto a cui non appartiene.

L'opzione 2 mi attrae di più finora, ma ha anche uno svantaggio: emetterà più% eventi di% co_de, se la raccolta di rename deve modificare nuovamente il nome stesso.

NB: Anche se sia il Pages (come Page::setParent( Pages $container ) può essere posseduto solo da una collezione) sia le funzionalità di dispacciamento degli eventi (principalmente destinate ai consumatori) sono già implementate, né sono utilizzate per il mio ancora un enigma di denominazione univoco.

Hai altri suggerimenti che soddisfano i vincoli che Page dovrebbe essere responsabile per la verifica dell'unicità e che non c'è bisogno di molte comunicazioni avanti e indietro?

1) Come riferimento: il mio obiettivo è simile al tipo di comportamento di Pages di Excel VBA, che a mio avviso si comporta in modo simile a quello che sto cercando.

    
posta Decent Dabbler 07.01.2018 - 07:27
fonte

1 risposta

5

L'unicità di questi nomi è una proprietà che è chiaramente definita solo nel contesto di una raccolta Pages . Questo è il più semplice da capire quando pensi a un oggetto Page che cambia il suo contenitore "genitore" o un oggetto Page senza alcun contenitore principale.

Quindi verificare l'univocità è chiaramente una responsabilità della classe Pages , non di una Page . Di conseguenza, quando il meccanismo di verifica / risanamento è implementato in Pages , è esattamente al suo posto. Chiamare questo meccanismo da Page::setName non cambia la responsabilità, quindi la tua "Opzione 1" è perfettamente a posto.

Come nota a margine: il più semplice "meccanismo di verifica / igiene" che posso pensare è semplicemente vietare qualsiasi modifica del nome di una Page una volta che è stata assegnata a una raccolta Pages . Questa semplice strategia potrebbe essere totalmente sufficiente per diversi casi d'uso. Se una pagina deve essere rinominata, prima deve essere estratta dalla raccolta, quindi rinominata e quindi aggiunta nuovamente utilizzando il metodo add nell'esempio.

    
risposta data 07.01.2018 - 10:38
fonte