Progettazione di alias di oggetti

2

Supponiamo di sviluppare un interprete o un file system. Ci sono oggetti, come variabili, procedure e file in qualche ambiente. Hanno un nome e un contenuto (la variabile ha un valore corrente, la procedura ha il corpo del codice e il file ha alcuni dati nel suo corpo). Puoi richiedere vbl1.value , proc2.execute e file3.content per ottenere i loro "valori" e puoi anche richiedere sempre il nome dell'oggetto corrente di (vbl|proc|file).name . Supponiamo di abilitare gli oggetti alias su un oggetto dato, alias(name, target) . Dice che l'alias ha il suo nome ma in qualche modo condivide il "valore" con il target. Come lo progetteresti?

L'implementazione dell'alias sarebbe strettissima se avessi oggetti separati dai loro valori. Tutti gli alias potrebbero condividere l'unico corpo e quindi l'oggetto principale potrebbe essere implementato come alias + anche il corpo.

D'altra parte, gli oggetti primari sono in corrispondenza 1 a 1 con i loro valori e non è saggio "preferire il controllo su override" per loro. Inoltre, la maggior parte degli oggetti non avrà gli alias e tale design è uno spreco di memoria (2 oggetti sono sprecati di memoria 2x in JVM). Ma se non dividiamo i nostri oggetti in nome + corpo, come implementare gli alias? Come proxy? Sembra una duplicazione di codice. La prima variabile di codice, proc, ... oggetti e quindi espandere queste classi con proxy appropriati. Anche trice, dal momento che ora gli oggetti devono essere interfacce che ammettono l'implementazione di prima classe e proxy. Inoltre, tale divisione rende valori / corpi "senza testa", non è possibile ottenere il nome, dato un corpo come proc1.name sopra. Probabilmente è giusto dal momento che il corpo sotto considerazione può essere accessibile attraverso uno qualsiasi degli alias ora.

Sto esitando. Ammetto che può esserci un approccio migliore. Quale è consigliato? Gli alias sembrano essere abbastanza in uso e quindi le linee guida generali devono esistere, sono sicuro ma non riesco a trovare nulla.

    
posta Valentin Tihomirov 12.02.2016 - 12:08
fonte

3 risposte

2

Nei filesystem ci sono due diversi tipi di link:

  • hard link: che punta a oggetti anonimi (ad esempio inode)
  • link simbolico: che può indicare il vero nome del file o un altro collegamento simbolico

In linguaggi come Python, alcuni oggetti come classi e funzioni hanno un nome canonico a cui si accede attraverso obj.__name__ . Rializzare l'oggetto con un altro nome o accedere all'oggetto dall'alias non cambia il nome canonico dell'oggetto.

Molte lingue hanno anche un concetto di riferimenti deboli, in cui gli oggetti sono avvolti da un oggetto di riferimento debole, che consente di eliminare l'oggetto.

Anche molte lingue hanno nozioni di nomi differenti. Le lingue dinamiche considerano i nomi come nozione di runtime e gli oggetti hanno nomi. I linguaggi statici considerano i nomi come costrutti del tempo di compilazione e tali riflessioni di nome vengono compilate su una stringa costante.

Se la tua lingua ha un naming dinamico, allora per me ha più senso che gli oggetti siano anonimi o abbiano nomi canonici. Se la tua lingua ha una denominazione statica, probabilmente vorrai che ogni volta che gli oggetti siano referenziati nel codice siano nomi diversi.

Se vuoi un linguaggio dinamico con nomi lessicali, allora sì, avresti bisogno di un oggetto wrapper ovunque.

    
risposta data 12.07.2016 - 06:02
fonte
0

Non conosco linee guida generali sull'uso degli alias.

Il mio pensiero iniziale sarebbe di usare i proxy, quindi per ogni tipo hai una variante alias che punta alla cosa reale.

Ma cosa succede quando un file che ha un alias viene distrutto, anche l'alias dovrebbe essere distrutto, quando è noto che l'alias dovrebbe essere distrutto?

Una soluzione è usare Observer pattern . Consentire all'oggetto originale di conoscere i suoi alias e lasciare che notifichi gli alias quando vengono distrutti. L'alias può quindi decidere di restare, o di distruggere se stesso.

Piccolo esempio in pseudo codice:

class File {
    string Name;
    string Content;
    IList<FileAlias> Aliases;
    void Destroy() {
        Aliases.each(x => x.NotifyDestroy());
    }
}

class FileAlias : File {
    File originalFile;
    string Name; // overriding original
    void Destroy() { }
    void NotifyDestroy() {
        orignalFile = null;
    }
}
    
risposta data 12.02.2016 - 13:33
fonte
0

Un alias è solo un altro tipo di oggetto. I dati sono un riferimento a qualche altro oggetto. QED.

La chiave del concetto di Alias è che è sottomessa all'oggetto principale. Se l'oggetto principale esce dall'ambito, l'alias non funzionerà più.

Spezzare i dati come una cosa a parte che sia gli oggetti che gli alias rimangono su non esprimere questa qualità.

Quindi sì, usa il pattern proxy. Non perché salva la memoria o utilizza più memoria (dopo tutto, la quantità di memoria di cui stiamo parlando, rispetto alla dimensione dei dati, è minuscola), ma perché esprime meglio ciò che un di Alias è . Non è solo un altro puntatore allo stesso dato, è necessariamente inferiore alla realtà.

    
risposta data 12.02.2016 - 13:25
fonte

Leggi altre domande sui tag