Newsgroup: it.comp.lang.visual-basic
Titolo: [?] sempre su OOP... oggetti globali? performance e memoria...

Ciao,
nell'applicazione che sto realizzando ci sono diverse calssi che
rappresentano
delle "utility" di uso abbastanza comune/frequente.
Per esempio l'I/O su file, l'accesso e la manipolazione del registry,
funzioni di analitica...
Mi chiedevo quale è la "giusta" (migliore?) impostazione  in un programma
3-tier per questi oggetti.
L'applicazione è multi-documento, quindi io ho una serie x di classi "cDoc",
che possono avere bisogno di accedere a queste utility..
avevo pensato 3"strade":
1) La classe "root" cApp (che contiene la collecion di cDoc) espone come
proprietà delle istanze di queste classi ,  1 istanza per utility = ~ 4
oggetti caricati in memoria
Quando istanzio nuove cDoc passo loro il riferimento a cApp e tramite questo
riferimento loro possono accedere alle utility (oppure meglio passo
direttamente il rif alle istanze per evitare circoli viziosi)
2)come la 1 ma cApp istanzia una classe che si occuperà di fare da provider
di servizi per conto di cApp, in questo modo passo ai cDoc il rif al
provider e non ho riferimenti circolari con cApp.. in + se devo aggiungere
utility non devo aggiungere proprietà a cDoc ma solo al Provider di
servizi...
3)ogni cDoc istanzia le sue copie di utility, ma così ho 4*(numero Doc)
oggetti caricati in memoria.. mi pare uno spreco di risorse
Sbaglio qualcosa? cosa ne pensate?
Davide

 avevo pensato 3"strade":
[SNIP]
Ce ne sarebbe anche un'altra, quella di usare classi statiche, dove i metodi
possono essere invocati facendo riferimento alla class stessa e non ad una
sua specifica istanza, e che sono proprio indicate per queste funzioni di
utilita' generiche che sono per lo piu' "stateless".
Sfortunatamente in VB6 questo tipo di classe non esiste, puoi pero'
simularla in maniera semplice, dichiarando una sola istanza di ciascuna in
un modulo BAS.
Il risultato che ottieni e' quello di avere un consumo minimo di risorse
come per le soluzioni 1 e 2, ma con il vantaggio di non dover passare
riferimenti in giro alle classi figlie (che se un domani diventano nipoti e
pronipoti, devi rimbalzare quel riferimento a destra e a manca...)
Se poi dai retta ad uno scemo, usa un piccolo accorgimento
"quadridimensionale"; dichiara le istanze con lo stesso nome della classe,
es:
Public cRegistry As cRegistry
(qui potrebbe valer la pensa dichiararle As New, ma se non vuoi questo
overhead, falle invece istanziare nel initialize di cApp)
in questo modo, se un domani passi ad un linguaggio un po' piu' OO,
ridefinisci cRegistry come statica, togli la dichiarazione e, voila',
funziona tutto.
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 un modulo BAS.
in effetti č quello che pensavo di fare.. perň forse č meglio se le istanze
le faccio generare nella
sub main() e non da cApp cosě le cose imangono separate :)
grazie
Davide

 un modulo BAS.
A quanto ho capito .. dovresti dichiarare delle variabili pubbliche, da cui
poi riferirti.
Magari, quella che ti propongo è una soluzione che hai già vagliato, però
...
lo spreco di risorse di cui parli nell'istanziare oggetti è dovuto al fatto
che per ogni metodo, evento property ecc.. scrivi del codice.
Ogni volta che istanzi la classe questa ricarica tutte le funzioni definite.
Quello che ti propongo è di trasferire tutte le tue funzioni in un modulo
BAS (rendendole public) all'interno della dll e di creare le classi che
facciano semplicemente da wrapper alle funzioni definite nel modulo standar.
La prima istanza che crei ti carica tutte le funzioni definite nel .bas.. ma
tutte le altre istanze no.
Ogni altra istanza dovrà si ridefinire tutte le funzioni ma solo le
intestazioni, in quanto il codice è presente in una parte di memoria già
caricata.
In pratica le istanze aggiuntive non dovranno più ricaricare tutte le
funzioni definite nel .bas.
Tutto questo PERO' funzione solo nello stesso thread ...
Saluti

 ha scritto nel messaggio
news:IdtZ9.127072$AA2.5...@news2.tin.it...

Giovane Skywalker, fidarti del Sub Main non devi tu...
Se il tuo programma e' un EXE ActiveX nulla ti garantisce che il Sub Main
venga eseguito *prima* della creazione della classe invocata dall'esterno, e
rischi di essere temporaneamente disallineato... credimi, ci e' gia'
successo che in determinate circostanze venisse invocato un metodo di classe
prima che la connessione al DB (messa nella Main) fosse stata aperta
Per cui, se dai retta allo stesso scemo di prima, racchiudi le tue
inizializzazioni critiche in una routine pubblica a parte, con un bel flag
"siamo hia' partiti?" e invocala sia dal Sub Main che dal Class_Initialize
di tutte le classi creabili (che nel tuo caso potrebbe essere solo cApp)
Per esempio:
Public Sub StartUp()
Static bStarted As Boolean
If Not bStarted Then
    '[...] il tuo codice di start up
    bStarted = True
End If
End Sub


 ha scritto nel messaggio
news:b15os5$vq10f$1...@ID-169051.news.dfncis.de...

[SNIP]
Funziona anche cosi', pero' rende piu' scomodo il riutilizzo dei sorgenti: o
compili una DLL di utilita' a parte (e a questo punto risolvi ancora meglio
utilizzando classi GlobalMultiUse) oppure ogni volta che vuoi includere una
classe in altri progetti devi sempre portarti dietro il BAS ...
Con le istanze pubbliche di classe il codice e' meglio incapsulato, e lo
spreco di risorse e' comunque ridotto al minimo (4 byte per il puntatore di
ogni classe utilita' per tutto il programma)



ok obi wan.. ahem Luca :D
Davide

Un'alternativa sarebbe l'implementazione del Pool pattern.
Che ne pensate?
Andrea

 Che ne pensate?
Quella si che č una soluzione .. anch'io avevo in mente una cosa del genere
...
solo una cosa non sono riuscito a capire ..
cos'č il pool pattern :)
Saluti

 Saluti
Andrea


Questo si .. è come vengono serializzate e servite le istanze dei vari
oggetti ... ma mi rimane ignota la definizione di pool pattern ..
potresti darmi una dritta ?
Saluti


Che hai sfoggiato una bella parola, ma stai dicendo la stessa cosa che
stiamo dicendo noi... dove li memorizzi in un programma VB i riferimenti
agli oggetti del pool? in un BAS, per forza di cose, altrimenti come fai a
limitare il numero di istanze da creare se il gestore del pool e' multiuse?
E siccome Davide ha bisogno di un unica istanza per ciascuna classe, mi
sembra una sofisticazione inutile creare un pool manager che restituisca un'
unica istanza delle classi che comunque deve essere public a livello di
modulo BAS: tanto vale usare direttamente quella...


 Saluti
Ciao
Andrea

 Ciao
Ciao
Andrea

 accedere ad una serie di risorse, giusto?
Sbagliato.
Ci sono piu' istanze di cDoc che devono accedere ad una serie di funzioni di
utilita' che si vogliono incapsulare in una o piu' classi; niente risorse,
niente thread, niente handle...
come dicevo, lo scenario mi sembra quello tipico delle classi e metodi
statici (in Delphi "class methods", mi pare...), che pero' non essendo
fattibili in VB possono essere ragionevolmente approssimati con una singola
istanza di classe pubblica per tutta l'applicazione; senza bisogno di un
pool, e senza bisogno di palleggiarsi i riferimenti da una classe all'altra
come nelle prime ipotesi di Davide
