STRUTTURA DEL PROGETTO E DEL DATABASE
I
codici sorgenti di Gea.Net sono disponibili a richiesta. Per maggiori
informazioni su come riceverli consultare http://www.fborghi.it.
I
codici sorgenti sono stati scritti in Visual Basic .NET pertanto per poterli
modificare è necessario installare sul proprio computer Visual Studio .NET 2003
Professional.
Le
due cartelle dove sono posti i sorgenti sono ..\GEANET e ..\CLASSNET con le
relative sottocartelle. E’ sufficiente copiare queste due cartelle sulla
radice del proprio disco C o in altra posizione assicurandosi di posizionarle in
modo che siano “sorelle” (es. C:\GEANET e C:\CLASSNET ). Di seguito
riporteremo “..\” per indicare la cartella padre.
Sia
GEANET che CLASSNET si compongono di diversi progetti che analizzeremo meglio in
seguito e sono racchiusi nella solution ..\GEANET\GEANET.SLN.
Pertanto
per accedere ai sorgenti, dopo aver aperto Visual Studio, dovrà essere aperto
“Apri Progetto” nel menu “File”, selezionando il file ..\GEANET\GEANET.SLN
Le
altre cartelle distribuite assieme ai sorgenti sono raccolte di software ed
esempi e non sono legate all’applicazione.
Nella
cartella principale si trova anche un file zippato GEANETS[versione].ZIP che
contiene i files da ridistribuire agli utenti finali.
La
cartella CLASSNET contiene alcuni progetti che possono essere riutilizzati anche
per solution diverse. Essi sono ripartiti per macroarea e non conoscono in alcun
modo quella che è l’attività di business. Allo stesso modo NON conoscono il
database e le form del progetto principale. Per mantenere portabili questi
progetti non deve essere utilizzato al loro interno un riferimento diretto agli
oggetti del progetto principale ma nel caso usare una classe generica o usare
tecniche di reflection per accedervi.
Le
sottocartelle di CLASSNET sono i progetti di cui esso si compone :
La
cartella GEANET contiene i progetti che rappresentano l’attività vera e
propria di Gea.Net.
I
progetti che lo compongono sono :
Il
seguente schema dovrebbe rendere più chiara la struttura e le dipendenze dei
progetti
Per completezza
dovrebbero essere inclusi nello schema precedente anche i moduli ClsB_BaseUC e
ClsB_BaseUC_Gruppi. Queste due librerie sono utilizzate nello stile WPF a
completamento di Cls_BaseForm .
Struttura
del Database
La
struttura del database è piuttosto spartana. Nella sua configurazione di base
non sono contenute relazioni, viste o stored procedure. Questa scelta rende
portabile il database su qualunque piattaforma anche se il software è testato
con SQLServer e Access. Se si vuole migrare ad un database diverso sarà
sufficiente intervenire sul modulo Dbfunct della classe ClsB_Base che racchiude
ogni funzione basilare di accesso al database ( apertura delle connection,
gestione dei dataset, datareader, ecc. ).
Durante
la stesura dell’applicazione si è tentato di utilizzare solo comandi SQL
standard per rendere agevole la portabilità anche a database meno strutturati,
tuttavia potrebbe essere necessario rivedere alcuni comandi nel momento in cui
si volesse migrare a database diversi da SQLServer e Access.
Naturalmente
questa scelta strutturale estremamente semplice penalizza le prestazioni della
applicazione. Per rendere più performante il software si consiglia di integrare
stored procedure rivedendo alcuni metodi interni alle classi di business.
La
struttura delle tabelle rispecchia a grandi linee la struttura delle classi
concentrando all’interno di una unica classe eventuali tabelle master-details.
Per aiutare la comprensione si è fatto uso di prefissi per cercare di
organizzare logicamente le tabelle anche se non esiste un disegno di relazioni
per non compromettere la portabilità del database.
La
scelta progettuale di non rendere vincolante un particolare database ha
comportato che non fossero utilizzati campi identità o tipi di campi
proprietari come i campi oggetto.
Componenti dell’applicazione
In
questa sede è difficile poter analizzare in dettaglio ogni singola funzione. Lo
scopo che ci si prefigge con questa breve guida è di dare una infarinatura sui
componenti del software e l’utilizzo che ne viene fatto. Il dettaglio sulle
modalità operative delle singole funzioni, quando non espressamente palese, è
documentato all’interno del codice stesso con esempi sull’utilizzo.
Si
ricorda che le librerie presenti in ClassNet sono astratte e possono essere
utilizzate in progetti diversi. Non troverete e non dovete inserire riferimenti
espliciti al database o all’applicazione in uso. Ogni nome (connectionstring,
nome di tabelle e di campi) deve essere agganciato dall’esterno come parametro
o proprietà o acquisito da file di configurazione esterno.
Per
le librerie di seguito, l’ordine di presentazione grafica è alfabetico per
consentire una più facile ricerca, mentre la descrizione operativa è in ordine
di importanza del componente.
ClsB_Base
ClsB_Base.dll
è la libreria base della solution. Viene utilizzata in tutti i progetti e
contiene classi e moduli di uso comune.
Global
(Modulo)
E’
un modulo che contiene una serie di utility di basso livello. Tra questi
rivestono particolare importanza le funzioni di conversione (con prefisso Conv)
che permettono di convertire variabili tra tipi diversi con la certezza di
gestire e risolvere le eccezioni. Particolarmente importanti anche le funzioni
di binding (Prefisso BindControl) che eseguono bind con gestione delle eccezioni
tra i diversi tipi di controlli e le variabili. Qui si trovano altre funzioni di
uso comune per l’arrotondamento, il controllo di congruità di codici,
inizializzazioni e settaggi, gestione ed invio di email, gestione delle date e
campi note, ecc.
GlobalF35
(Modulo)
E’
un modulo che contiene una serie di utility di basso livello simile a Global
tuttavia contiene funzioni disponibili solo con .NET Framework 3.5 . La
creazione di un secondo modulo si è resa necessaria per garantire la
compatibilità di Global con versioni precedenti.
DbFunct
(Modulo)
Dbfunct
è l’unica porta di accesso al database. Tutte le classi che vedremo di
seguito passeranno dalle funzioni di DbFunct per colloquiare con la base dati.
Tutte le classi (connection, DataReader, DataAdapter, ecc.) sono astratte.
Questa scelta riveste particolare importanza perché consente di agganciare un
nuovo database con estrema facilità.
Questo
modulo è in grado di riconoscere il tipo di database dalla connectionstring ed
in base a questa operare di conseguenza.
La
funzione più importante è ExecuteSQL che esegue un comando (SELECT, INSERT,
UPDATE o DELETE). Se il comando e' sotto
transazione Command e Connessione sono importate dall'esterno. Usa
ExecuteNonQuery per avere maggior velocità o ExecuteReader per ritornare un
dataReader (Select o Stored Procedure). Il parametro RigheTrattate passato ByRef
ritorna il numero di Righe oggetto di modifica/cancellaziome
I
diversi database possono avere differenze sintattiche. Anche le funzioni di
generazione delle stringhe e conversione tra tipi sono contenute in DbFunct.
IO
(Modulo)
IO
permette la gestione di files e cartelle (generazione, copia, cancellazione,
verifiche, ecc.).
Gestisce
la serializzazione, l’upload e il dowload di files, la lettura e scrittura di
file di testo.
Form
(Modulo)
Questa
modulo contiene funzioni di base che consentono di gestire le winform e le
pagine web.
Particolarmente
importanti le funzioni SetForm e SetPage che uniformano i controlli presenti
sulle pagine. In realtà SetPage può essere visto come un doppione dei file CSS.
DbClass
(Classe)
DBClass
e' una classe che permette il caricamento da data di un record, lo puo' gestire
e riscrivere. Tutte le classi di business gestite nell’applicazione saranno
ereditate da DbCless. Pur non essendo una regola possiamo dire che una
sottoclasse corrisponde ad una tabella importante del database. DbClass permette
di gestire le classi master/datails come ad esempio documento/righe documento. DbClass
si avvale della classe DbClass_Module per le stampe delle schede.
DBClass
puo' operare autonomamente ma puo' anche collaborare con DBMaster, che vedremo
in seguito, per gestire le proprietà ricavate dalla classe.
DbReader
(Classe)
DBReader
consente la scansione di una tabella, query, stored procedures, ecc. in modo
veloce e con scorrimento solo in avanti e senza la gestione di cursori. Non e'
permesso il riposizionamento e la modifica dei dati (per questo c'e' DBMaster)
DbMaster
(Classe)
DBMaster
è figlia di DbReader e ne eredita le funzioni me può operare autonomamente e
può anche collaborare con
DBClass
per gestire le proprietà della classe.
DataGridManager
(Classe)
DataGridManager
consente la gestione dellle classi linkate a DataGridView fornendo dei metodi
per le operazioni piu' usate sulla griglia. Il costruttore linka un DataGrid ad
un oggetto DbMaster o DbClass. Sostanzialmente la possiamo vedere come una
classe che si occupa di fare binding tra DbClass e
ClsB_BaseForm.SuperDataGridView.
Questa
classe è utilizzate nella gestione dei dettagli agganciati a classi DbClass o
nella presentazione dei dati nella form di elenco.
Printer
(Classe)
L’utilizzo
delle stampanti in Vb.Net/C# non è così banale come in Visual Basic. Printer
cerca di rendere semplice l’accesso e la gestione delle stampanti.
L’utilizzo di Printer permette di fare stampe grafiche e stampe di testo, cioè
comporre e stampare righe come si faceva su sistemi operativi privi di driver.
Le
stampe grafiche di base possono riportare testo, immagine, codice a barre, linee
e rettangoli. Ogni oggetto può essere definendo un punto (X e Y in cm) di
inizio e di fine.
Per
le stampe in formato PDF o RTF deve essere utilizzato PrinterDoc (figlio di
Printer) compreso in ClsB_Office
Errore
(Classe)
Le
eccezioni sono gestite nella classe errore. Le eccezioni sono tracciate in
ordine di evento sul file ..\bin\DATI\Log\ErrorLog_[data].txt
Log
(Classe)
Le
operazioni eseguite dagli utenti sono gestite nella classe Log e tracciate in
ordine di evento sul file ..\bin\DATI\Log\InfoLog_[data].txt
Translater
(Classe)
Si
occupa della gestione delle traduzioni delle label presentate a video o in
stampa. Si appoggia ad un file XML gestito in “Gestione Tabelle” che
contiene una riga per ogni termine o frase e una riga per ogni lingua.
XML_Table e XMLXPathReader (Classe)
XML_Table
permette di gestire una o piu tabelle su dataset. XMLXPathReader serve
per poter effettuare delle query o sort XPath su un documento XML.
ClsB_BaseForm,
ClsB_BaseUC, ClsB_BaseUC_Gruppi
ClsB_Base.dll
è la libreria base per la gestione delle form. Viene utilizzata in tutti i
progetti che hanno interfaccia winform. Contiene form madri e controlli utente
utilizzate nelle form figlie.
Le
form presenti nell’applicazione sono uniformi nella gestione e nei metodi.
Infatti, ad eccezione delle form più banali,
ereditano tutte da GestForm o BaseForm.
GestForm
(Classe)
GestForm
e' la form genitrice delle form di
gestione. GestForm generalmente genera form che gestiscono le classi di business
(ogni form figlia si occupa di gestire una classe) ma si presta anche a gestire
tabelle senza che sia definita una specifica classe.
Contiene
metodi per creare un nuovo oggetto, aprirne uno esistente, salvare l’oggetto,
cancellarlo, stamparlo. Mette a disposizione menu che possono essere integrati.
Queste funzioni di base naturalmente vengono arricchite con funzioni specifiche
dalle clessi filglie ma l’importante in questa sede è avere funzioni astratte
che possano essere ereditate ed utilizzate da tutte.
All’interno
della libreria troviamo UTIL01 e TableManager che sono due esempi di classi
figlie di GestForm. UTIL01 permette di gestire i dati anagrafici dell’azienda
e di salvarli su file config.xml. TableManager è più complessa perché
interagisce con il database dovendo mantenere un grado di astrazione. Per fare
questo i riferimenti alle tabelle e ai campi da gestire arrivano dall’esterno
sotto forma di classi o di semplici array.
BaseForm
(Classe)
GestForm
e' la form genitrice delle form di
presentazione. Anche in questo caso possiamo agganciare alla form figlia una
classe di business che rende estremamente veloce la creazione di selezioni anche
complesse.
Contiene
un metodo per eseguire un’operazione (solitamente la presentazione di una
griglia ma altre volte la chiamata a metodi). Mette a disposizione menu che
possono essere integrati. Queste funzioni di base vengono arricchite con
funzioni specifiche dalle clessi figlie.
CollectionManager
(Classe)
La
form figlie di GestForm che si occupano di presentazione, alla richiesta di
selezione, presentano una form che chiede i dati che si vogliono visualizzare.
Questa form è la CollectionManager. Il popolamento della CollectionManager
deriva da una collection popolata dalle classi di business.
Search
(Classe)
La
form Search permette di ricercare una registrazione conoscendo parte del codice
o parte della descrizione di una riga o eventualmente altri campi a scelta dello
sviluppatore. Search viene chiamata soprattutto da LinkTable o da
SuperDataGridView ma può essere utilizzata in diversi punti
dell’applicazione.
GrigliaTC
(Classe)
La
form GrigliaTC gestisce la griglia Taglie e Colori. Viene chiamata da LinkTable
o da SuperDataGridView.
SuperDataGridView
e SuperDataGrid (Classe User Control)
La
gestione di DataGridView e DataGrid (fino al framework 1.1) non è
particolarmente semplice per il numero di metodi e proprietà che queste mettono
a disposizione. Soprattutto il binding proposto da questi controlli non è
particolarmente funzionale e non riesce a gestire query complesse e con diversi
join.
SuperDataGridView
e SuperDataGrid consente di superare
questi problemi fornendo metodi ben definiti per le operazioni piu' usate sulla
griglia. Lavorano in stretto rapporto con ClsB_Base.DataGridManager e di
consegunza gestiscono i dettagli presenti nelle classi di business.
SuperDataGridView
e SuperDataGrid permettono anche una presentazione veloce e automatica nella
presentazione dei dati nella form di elenco.
Il
menu di contesto mette a disposizione funzioni per la stampa e l’esportazione
della griglia in formato XML, HTML e Excel.
LinkTable
(Classe User Control)
Lo
user control LinkTable permette di agganciare un codice e una descrizione di una
tabella. Naturalmente LinkTable è una classe astratta pertanto i nomi dei campi
e delle tabelle sono proprietà che devono essere caricate dall’esterno.
SuperListView
(Classe User Control)
Si
presenta come SuperDataGridView ma a differenza di questa è di sola lettura. In
realtà il componente di base è notevolmente diverso infatti la presentazione
avviene su una ListView. In diverse funzioni dell’applicazione SuperListView e
SuperDataGridView sono previsti entrambi quindi sono intercambiabili ma le
caratteristiche sono leggermente diverse.
Si
consiglia di utilizzare SuperListView quando si vuole creare una form più
leggera, se i dati riportati non sono bindati direttamente da una tabella,
quando si vogliono presentare griglie con presentazioni grafiche differenti per
cella. Alcune di queste possibilità si possono ottenere anche con
SuperDataGridView ma la quantità di lavoro di sviluppo richiesto è maggiore.
SuperTextBox
(Classe User Control)
Utilizzare
questo componente invece di TextBox quando si deve inserire nomi di file,
indirizzi email, siti web, ecc.
Sono
permesse la ricerca e la presentazione dell’oggetto inserito.
SuperRadioButton
(Classe User Control)
Permette
di estendere l’oggetto Radio Button affinché vada in binding con variabili di
tipo integer.
UC_DatiAnag
(Classe User Control)
Tra
le strutture presenti in ClsB_Base.Global troviamo DatiAnag che contiene le
proprietà dei dati anagrafici (ragione sociale, indirizzo, città, ecc.).
Questo controllo permette il binding con variabili di tipo DatiAnag.
ClsB_BaseUC,
ClsB_BaseUC_Gruppi (LIBRERIE)
Le
librerie ClsB_BaseUC e ClsB_BaseUC_Gruppi contengono user control
simili a quelli della libreria ClsB_BaseForm con nomi leggermente diversi
(di solito la classe ha lo stesso nome con il prefisso UCWPF_).
Come
si può avere intuito le funzionalità sono le stesse dei controlli
precedentemente trattati ma sono usate per lo stile WPF (Windows Presentation
Foundation).
Fin
dove possibile anche il nome dei controlli, delle proprietà, dei metodi e degli
eventi è stata mantenuta. Questo aiuta lo sviluppatore anche e soprattutto
nell’utilizzo degli user control in form (stile FORM) e window (stile WPF) che
hanno la stessa funzione.
Anche
in questo caso la creazione di librerie separate si è resa necessaria per
garantire la compatibilità di ClsB_BaseForm con versioni precedenti.
La
creazione di due assembly diversi è stata dettata dall’esigenza di
raggruppare in un assembly a parte (ClsBUC_Gruppi) user control che contengono
altri user control.
ClsB_Sistema
ClsB_Sistema.dll
è la libreria che racchiude metodi e classi per interagire con il sistema e con
Active Directory. Si tratta per lo più di best-practice piuttosto che di un
ambiente strutturato e le funzioni che si trovano qui vengono utilizzate il più
delle volte in ambienti di nicchia o in personalizzazioni. Tuttavia qui potete
trovare parti di codici che risolvono con poco sforzo una particolare esigenza.
SysNet
(Modulo)
Contiene
alcune funzioni non accessibili dal framework per raccogliere informazioni sul
sistema e sugli utenti.
Zip
(Modulo)
Permette
di zuppare/unzippare files o cartelle. Il file zip generato può essere letto da
applicativi come WinRAR o WinZip ma non da Windows.
FtpCommand
(Classe)
Gestisce
la connessione con un sito FTP gestendo download, upload e lista dei file.
Services
(Classe)
Consente
di verificare quali servizi Windows sono attivi.
EventLog
(Modulo)
Funzioni
per la gestione degli eventi di log di Windows.
Security
(Modulo)
Contiene
alcune funzioni per leggere identità, credenziali e firma digitale.
ClsB_Office.dll
è la libreria che racchiude metodi e classi per interagire con file e strumenti
di office automation. La parte del leone la fanno oggetti Micorsoft Office e PDF.
PrinterDoc (Classe)
PrinterDoc
è figlia di ClsB_Base.Printer e ne eredita tutte le caratteristiche con la
differenza che anziché generare una stampa, in output genera un file PDF o RTF.
MSOffice
(Classe)
Questa
classe gestisce un file di Microsoft Office (Word, Excel o Project). Anche in
questo caso più che di una classe strutturata possiamo vederla come una classe
nata per gestire le singole esigenze. Pertanto potremo sostituire una parola in
Word per avere un template da riutilizzare, potremmo leggere e scrivere celle in
Excel o gestire i progetti inseriti in Micosoft Project. Per svolgere queste
funzioni sono stati utilizzati gli oggetti di Micosoft Office ovvero OCX.
Per
rendere la classe modificabile anche su PC che non abbiano Micosoft Office
installato tutte le classi sono di tipo object.
DocRtfPdf
(Classe)
DocRtfPdf
permette di generare un documento in formato Pdf o Rtf. Può essere generato un
documento da un file XML o inviato un documento su webform.
Zetafax
(Classe)
Invia
Fax attraverso ZetaFax Server con ZetaFax CommsEngine.
Per
rendere la classe modificabile anche su PC che non abbiano ZetaFax
installato tutte
le classi sono di tipo object.e viene
usato latebinding (CreateObject).
Per
poter utilizzare queste funzioni l’utente deve aver acquistato le licenze di
Zetafax.
Per inviare un allegato in formato PDF o DOC deve essere installato sul server la licenza di 'Document Conversion'.
ClsB_Gea e
ClsB_GeaForm
Le
classi specifiche dell’applicazione sono composte di diverse decine di classi.
La necessità di creare due librerie piuttosto che una sola è dettato
dall’esigenza di rendere scalabile l’applicativo anche a servizi esterni o
applicazioni WEB.
ClsB_Gea
contiene tutte le classi di business, cioè classi astratte che non hanno alcuna
relazione con l’intercaccia utente. Di
conseguenza è la libreria fondamentale e qui troveremo tutte le funzioni
nevralgiche, strutturate per classi di appartenenza.
ClsB_GeaForm
invece si occupa di relazionare le classi con l’utente, qui troviamo alcune
form di uso comune o alcuni controlli utente. Naturalmente la maggior parte
delle form si trovano nelle librerie specifiche (AIM_*).
Trattare
le diverse classi in dettaglio in questa sede sarebbe molto complicato. Basti
sapere che l’uso che viene fatto delle diverse classi è esplicitato nel nome
stesso e i metodi sono generalmente commentati all’interno del codice stesso.
Generalizzando
possiamo dire che ogni classe ha un rapporto uno a uno con una tabella del
database (o uno a molti nel caso di gestione master/detail come ad esempio
ordine/righe ordini).
Allo
stesso modo possiamo dire che di solito abbiamo un rapporto uno a uno tra la
classe e la form che la gestisce pertanto nella maggior parte dei casi avremo un
le game diretto tra le entità :
Il
binding tra queste entità avviene utilizzando classi e funzioni di ClsB_Base.
Il binding tra tabelle e classi è gestito in TrattaListaCampi e in TrattaDettagliListaCampi di ClsB_Base.DbClass.
Il binding tra Classe e Form è garantito dalla funzione AssociaControlli che si
trova nella form e che riporta questa operazione a ClsB_Base.BindControl.
Nella
maggior parte dei casi le classi di business sono di primo livello ovvero sono
direttamente figlie di ClsB_Base.DbClass ma in alcuni casi possono avere un
ulteriore livello (ed esempio sia Ordini che Fatture sono figlie di Documenti
che è figlia di DbClass).
Questo
è il progetto di avvio dell’applicazione. In realtà è un progetto piuttosto
leggero e contiene solo la form di avvio e le funzioni di configurazioni ( il
cui lavoro viene eseguito in ClsB_Base ).
Il
progetto non contiene un riferimento diretto ai diversi moduli (AIM_*) come ci
si potrebbe aspettare. I moduli vengono interrogati e invocati tramite
reflection. Questo rende la gestione dell’applicativo più semplice e
polimorfica.
Infatti
a livello di sviluppo non abbiamo l’obbligo di integrare tutti i progetti che
lo compongono che, si badi bene, non sono solo quelli comuni ma possono anche
essere progetti di sviluppi verticali o personalizzazioni di un determinato
utente.
Anche
la gestione operativa ne trae vantaggio infatti è sufficiente eliminare una
libreria di modulo senza rendere instabile l’applicazione.
Le
librerie di modulo vengono chiamate per convenzione con il prefisso AIM. Esiste
una libreria per ogni modulo gestito pertanto nella solution sono presenti
diversi progetti AIM_*.
Le
librerie di modulo sono generate in formato dll e non possono essere eseguite
autonomamente ma devono essere invocate dall’esterno nel seguente modo :
Ogni
progetto contiene un interfaccia che per convenzione si chiama [nome_progetto].vb
che implementa iBF_AddInModule.
iBF_AddInModule contiene
tre metodi fondamentali per colloquiare con l’esterno :
A
questo punto abbiamo tutto ciò che ci serve per utilizzarla.
La
libreria si compone di normali form (stile FORM) e window (stile WPF) o classi
secondo le specificità della classe stessa.
Oggetti del database
Vale
la pena spendere due parole anche per la struttura del database pur essendo
abbastanza intuitivo l’uso delle tabelle.
La
prima cosa da sapere è che le tabelle hanno un prefisso nel nome che ne
identifica il gruppo di appartenenza.
Quindi
:
· AN : Anagrafiche clienti e fornitori
·
BO :
Documenti di trasporto
·
CA :
Risorse Umane (Presenze)
·
CE :
Cespiti
·
CV:
Risorse Umane (Curriculum)
·
FA :
Fatture
·
FF :
Documenti passivi
·
LS :
Listini
·
MA :
Magazzino
·
MC :
Movimenti di contabilità
·
MM :
Movimenti di magazzino
·
NO :
Noleggio
·
OR :
Ordini
·
PC :
Piano dei conti
·
ST :
Risorse Umane (Consuntivi presenze)
·
TA :
Tabelle generiche
·
TU :
Risorse Umane (Turni)
Si
ricordi che nel pacchetto base non sono stati utilizzati altri oggetti oltre
alle tabelle non disponibili in tutti i database (es. macro, relazioni, stored
procedure, trigger ). Questa scelta va a discapito della velocità di esecuzione
ma ha il vantaggio di non vincolare l’applicazione ad uno specifico database
garantendone la scalabilità. Le relazioni tra tabelle è gestito a livello
software e quindi bisogna fare particolare attenzione a questo aspetto durante
lo sviluppo di nuove funzioni.
Qualora
si realizzino funzione specifiche e personalizzazioni potrebbe essere
vantaggioso usare oggetti più performanti confinandoli in librerie diverse da
quelle comuni. In altri casi potrebbe essere conveniente sostituire alcune
classi o funzioni che anziché puntare ad una tabella, acquisiscano i dati
da una stored procedure o da una vista.
Gli
indici proposti sono ridotti al minimo ma per velocizzare alcune funzioni più
ricorrenti potrebbe essere il caso di generarne altri.
Tutti
questi aspetti devono essere analizzati secondo le esigenze e le richieste del
cliente.