PDA

View Full Version : [C#/Db qualsiasi]Consigli su progettazione


RaouL_BennetH
20-10-2008, 11:58
Buongiorno a tutti :)

Allora, ho il classico problema di un'applicazione windows forms.

Vorrei capire come gestire le operazioni sul database in maniera pulita.

Mi spiego:

In genere io per ogni tabella che ho sul database, mi creo una classe:


//Tabella Anagrafica del db:
cognome
nome
telefono
etc..

//Classe Anagrafica.cs
private string cognome;
private string nome;
private string telefono;

//valorizzo i campi mediante proprietà nella classe:
public String Cognome
{
get { return cognome; }
set { cognome = value; }
}
//blabla



Adesso, devo prendere i valori dal mio form ed inserirli sul database;
generalmente anche per le operazioni sul database uso una classe separata e, ad ogni modo, non uso mai inserire direttamente i valori presi dalle varie textbox ma utilizzo (a prescindere dal db) dei sql parameters.

Quindi in genere le operazioni che faccio sono:


//dal form che contiene le varie textbox:
ClasseAnagrafica anagrafica = new ClasseAnagrafica();
anagrafica.Cognome = txtCognome.text;

//blabla


Fatto questo, istanzio poi la classe che contiene i metodi per le operazioni sul db e inizializzo i sql parameter:


DbClass db = new DbClass();
SqlParameter cognome = new SqlParameter("@cognome", DbType.String);
cognome.Value = anagrafica.Cognome;

//etc...


Come potrete vedere, il tutto risulta un guazzabuglio orribile e credo poco efficace.

Per favore, datemi qualche consiglio su come iniziare a fare le cose in maniera pulita :help:

Potrei fare tutto nel form dove risiedono i miei oggetti, ma come mi hanno suggerito più volte un form è solo un contenitore e non è pratico infarcirlo di metodi.

Grazie mille.

RaouL.

Einstein
21-10-2008, 08:00
Il discorso è parecchio ampio...
La prima cosa che ti consiglio di fare separare bene le responsabilità e "stratificare" l'applicazione: un assembly per gli oggetti di dominio, in modo da poterlo referenziare comodamente negli altri layers, un assembly per l'accesso ai dati (Data Access layer o DAL) e l'assembly principale dell'applicazione.
Il tuo oggetto Persona sarà quindi definito dell'assembly degli oggetti di dominio (Domain Model), in questo modo:


public class Persona
{
public Persona() {}

public int Id;
public string Nome;
public string Cognome;
}



Tutti i metodi del DAL restituiranno delle istanze di oggetti di dominio oppure List<domainobject> nel caso di collection di oggetti.
Nel DAL puoi utilizzare il pattern Table Data Gateway, in modo da avere una classe che ti gestisca la logica CRUD (Create, Read, Update, Delete) per ogni singola tabella del db. Un'ipotetica classe di DAL che accede all'anagrafica potrebbe avere i seguenti metodi:


Persona GetById(int idPersona)
List<Persona> GetAll()
int Insert(Persona persona)
int Update(Persona persona)
int Delete(Persona persona)


La tua logica applicativa puo risiedere nell'assembly dell'applicazione (Presentation Layer), oppure in un apposito assembly di application logic, che ti permetterebbe di avere la logica applicativa non legata ad uno specifico tipo di interfaccia.
Qualche link su questi concetti:

Domain Model: http://martinfowler.com/eaaCatalog/domainModel.html
Table Data Gateway: http://martinfowler.com/eaaCatalog/tableDataGateway.html
Service Layer: http://martinfowler.com/eaaCatalog/serviceLayer.html

Spreo di essere stato abbastanza chiaro: l'argomento è vasto ed esistono quintali di letteratura riguardante l'architettura delle applicazioni e il software design.
Infine un consiglio: non sforzarti a fare tutto nella maniera più "pulita" solo perché fa "fico". Visto che il design di un'architettura può portarti via diverso tempo, tienine conto, visto che l'applicazione, prima o poi, dovrai consegnarla... :)

RaouL_BennetH
21-10-2008, 08:15
Grazie Einstein :)

Sei stato chiarissimo.

Fortunatamente non ho pressione sui tempi di consegna (non essendo io un programmatore di professione).

E' solo che mentre sviluppo (per hobby o per conto di qualche amico che richiede software senza pretese) mi vengono sempre mille dubbi e mi faccio sempre mille domande. Certe volte mi chiedo addirittura se abbiano senso.

Ma, vedendo il codice che viene fuori man mano, a 'orecchio' mi rendo conto che è sbagliato. Di preciso non saprei neanche dirti io il perchè, ma intuisco che, seppure ottengo il risultato desiderato, l'ottengo per strade lunghe e tortuose :p

RaouL.

RaouL_BennetH
21-10-2008, 14:01
Un altro dubbio....:

generalmente i forms sono molto diversi fra loro e contengono anche oggetti diversi (combobox, checkbox, griglie, textbox, etc..)

Al punto in cui sono, non riesco a vedere un modo "complessivo" per scrivere una classe che abbia metodi comuni a tutti, se non per le operazioni sul db ma, anche qui, i dati da inserire/aggiornare, sono sempre diversi.

Al momento posso quindi solo semplificare e adattare le mie conoscenze attuali.

Chiedo quindi una cosa:

E' saggio/giusto avere per ciascun form il suo modo di scrivere/leggere i dati ?

Faccio un esempio:

Creo una lista direttamente dalla classe del form:


List<string> anagrafica = new List<string>();

anagrafica.Add(txtCognome.Text);
anagrafica.Add(txtNome.Text);

//bla
//su un altro form avrò altri dati... quindi:
List<double> pagamenti = new List<double>();
pagamenti.Add(double.Parse(txtBolloAuto.Text);
pagamenti.Add(double.Parse(txtAssicurazioni.Text);

//blabla


C'è da considerare però che queste due liste diverse, riferite all'interazione dell'utente sui rispettivi forms, hanno un elemento in comune:

id_anagrafico (per esempio).

Mi fermo qui :)

Grazie mille.

RaouL.

Einstein
22-10-2008, 07:56
Non ho capito bene il tuo dubbio... Perché crei liste (di stringhe) direttamente dall'interfaccia?

RaouL_BennetH
22-10-2008, 08:24
Non ho capito bene il tuo dubbio... Perché crei liste (di stringhe) direttamente dall'interfaccia?

Ciao :)

Cerco di spiegarmi meglio:

Sono arrivato a questa soluzione:

Form -> Classe che si occupa di ricevere i dati del form -> Classe operazioni db;

Ma, in considerazione del fatto che un form è una classe come tutte le altre, non sarebbe meno dispendioso :

Form -> Classe operazioni db ?

Grazie mille :)

RaouL.

Einstein
22-10-2008, 14:37
Secondo me, hai due possibilità:

1. Dalla form invochi dei metodi di logica applicativa (che magari risiedono in un assembly separato) che si preoccupano poi di interagire con il db. La tua applicazione quindi non "vede" direttamente il db.

2. Aggiungi un riferimento al DAL nella tua applicazione, quindi le tue forms invocheranno direttamente i metodi del DAL.

Secondo me la "Classe che si occupa di ricevere i dati del form" non ha molto senso.
Ovviamente non conosco il contesto esatto del tuo applicativo, quindi potrei sbagliarmi...

RaouL_BennetH
05-11-2008, 07:58
Secondo me, hai due possibilità:

1. Dalla form invochi dei metodi di logica applicativa (che magari risiedono in un assembly separato) che si preoccupano poi di interagire con il db. La tua applicazione quindi non "vede" direttamente il db.

2. Aggiungi un riferimento al DAL nella tua applicazione, quindi le tue forms invocheranno direttamente i metodi del DAL.

Secondo me la "Classe che si occupa di ricevere i dati del form" non ha molto senso.
Ovviamente non conosco il contesto esatto del tuo applicativo, quindi potrei sbagliarmi...

E' proprio su questi punti che mi sono arenato.

Ho trovato una marea di documentazione in rete, ma sinceramente mi è servita più che altro ad aumentare la mia confusione :(

Un esempio di DAL abbastanza chiaro e alla portata di un newbie dove potrei trovarlo ?

Grazie mille.

RaouL.