Implementazione della logica del progetto - Codiclick

condividere

Implementazione della logica di progettazione

Annunci

Filosofie di approccio all'implementazione

approccio a cascata

L'approccio a cascata all'implementazione di un'applicazione richiede che un progettista consulti uno o più rappresentanti dell'organizzazione dell'utente finale e annoti tutte le specifiche dell'applicazione. In genere, le specifiche si presentano in un insieme di documenti funzionali o casi d'uso, scritti in modo tale che l'utente finale possa leggere e comprendere facilmente i documenti.

L'utente finale firma questi documenti e i documenti vengono quindi raccolti dal team di progettazione tecnica che progetta l'applicazione, creando vari artefatti come diagrammi del modello di classe, diagrammi di stato, diagrammi di attività e modelli di dati. L'obiettivo di questa fase è scrivere tutto in modo così dettagliato che uno sviluppatore non avrà problemi a creare il codice necessario. C'è una consegna formale del progetto al team di sviluppo e al team di test. Dopo la consegna, il team di sviluppo inizia a codificare e il team di test utilizza la progettazione tecnica in combinazione con i casi d'uso per creare casi di test e scenari di test.

Dopo che il team di sviluppo ha terminato la codifica, il codice viene consegnato al team di test. Il team di test esegue i test che ha progettato in base ai requisiti e al progetto dettagliato. Eventuali problemi verranno risolti dal team di sviluppo. Una volta completato il processo di test e correzione, l'applicazione viene consegnata all'utente finale per il test di accettazione. L'utente finale esegue un controllo finale per vedere se l'applicazione è conforme ai requisiti iniziali. Se approvato, approva il prodotto finito e il progetto è completato. Dopo che il team di sviluppo ha terminato la codifica, il codice viene consegnato al team di test.

Il team di test esegue i test che ha progettato in base ai requisiti e al progetto dettagliato. Eventuali problemi verranno risolti dal team di sviluppo. Una volta completato il processo di test e correzione, l'applicazione viene consegnata all'utente finale per il test di accettazione. L'utente finale esegue un controllo finale per vedere se l'applicazione è conforme ai requisiti iniziali. Se approvato, approva il prodotto finito e il progetto è completato. Dopo che il team di sviluppo ha terminato la codifica, il codice viene consegnato al team di test. Il team di test esegue i test che ha progettato in base ai requisiti e al progetto dettagliato.

 Eventuali problemi verranno risolti dal team di sviluppo. Una volta completato il processo di test e correzione, l'applicazione viene consegnata all'utente finale per il test di accettazione. L'utente finale esegue un controllo finale per vedere se l'applicazione è conforme ai requisiti iniziali. Se approvato, approva il prodotto finito e il progetto è completato.

L'utente finale esegue un controllo finale per vedere se l'applicazione è conforme ai requisiti iniziali. Se approvato, approva il prodotto finito e il progetto è completato. L'utente finale esegue un controllo finale per vedere se l'applicazione è conforme ai requisiti iniziali. Se approvato, approva il prodotto finito e il progetto è completato.

Un progetto può avere più o meno fasi quando si utilizza l'approccio a cascata, ma la caratteristica chiave è un inizio e una fine molto formali di ogni fase, con risultati molto formali.

Il vantaggio dell'approccio a cascata è che la responsabilità del team responsabile di ciascuna fase è maggiore. È chiaro cosa devono consegnare, quando devono consegnarlo e a chi devono consegnarlo. Spesso, il team di sviluppo non avrà bisogno di interagire con l'utente. Questo può essere molto utile quando si esternalizza lo sviluppo in un altro paese.

Il principale svantaggio dell'approccio a cascata è che, in un ambiente in cui tutto è organizzato in modo molto formale, la flessibilità di rispondere ai cambiamenti diminuisce. Anche gli spostamenti devono essere organizzati. Pochissime aziende sembrano farlo in modo efficace, spesso determinando un aumento significativo dei costi generali. Per gestire i costi di un progetto, alcune aziende ritardano persino eventuali modifiche ai requisiti fino alla consegna iniziale dell'applicazione, fornendo di fatto un'applicazione che non soddisfa le esigenze dell'utente finale.

sviluppo agile

Molti progetti di sviluppo software di lunga durata hanno superato il budget e non hanno consegnato il prodotto in tempo. La premessa della filosofia di sviluppo software agile è ridurre al minimo i rischi sviluppando software in tempi brevi, chiamati iterazioni, che in genere durano da una a quattro settimane. Ogni iterazione è come il proprio progetto software in miniatura e include tutte le attività necessarie per rilasciare l'incremento di nuove funzionalità: pianificazione, analisi dei requisiti, progettazione, codifica, test e documentazione. Mentre un'iterazione potrebbe non aggiungere funzionalità sufficienti per garantire il rilascio del prodotto, un progetto software agile mira a essere in grado di rilasciare nuovo software alla fine di ogni iterazione. Alla fine di ogni iterazione, il team rivaluta le priorità del progetto.

L'obiettivo dello sviluppo software agile è raggiungere la soddisfazione del cliente attraverso la consegna rapida e continua di software utile; mirando sempre a costruire ciò di cui il cliente ha bisogno; accogliere, piuttosto che opporsi, modifiche tardive ai requisiti; adattarsi regolarmente alle mutevoli circostanze; avere una collaborazione stretta e quotidiana tra imprenditori e sviluppatori, in cui la conversazione faccia a faccia è la migliore forma di comunicazione.

Il vantaggio principale dello sviluppo software agile è la flessibilità nell'affrontare i cambiamenti, puntando sempre a soddisfare le esigenze aziendali. Lo svantaggio, ovviamente, è un aumento della complessità della gestione dell'ambito, della pianificazione e del budget. Un altro rischio comune è l'attenzione limitata alla documentazione (tecnica).

Sviluppo incrementale

Lo sviluppo software incrementale è un mix di sviluppo agile e a cascata. Un'applicazione è progettata, implementata e testata in modo incrementale in modo che ogni incremento possa essere consegnato all'utente finale. Il progetto non è completato fino al completamento dell'ultimo incremento. Mira ad accorciare la cascata definendo incrementi intermedi e sfruttando alcuni dei vantaggi dello sviluppo agile. Sulla base del feedback ricevuto su un incremento precedente, è possibile apportare modifiche durante la consegna dell'incremento successivo. L'incremento successivo può consistere in nuovo codice e modifiche al codice fornito in precedenza.

Il vantaggio è che le formalità rimangono in vigore, ma la gestione del cambiamento diventa più semplice. Il costo del test e della distribuzione di un'applicazione più volte sarà maggiore rispetto a farlo una sola volta.

Programma di controllo del flusso

La scelta di un approccio al controllo del flusso di programma è un compito molto architettonico. L'obiettivo è creare un progetto della tua applicazione in cui, una volta che inizi ad aggiungere funzionalità e codice, ogni cosa sembra avere il suo posto. Se hai mai rivisto o scritto codice di alta qualità, comprendi questo principio.

Codice organizzatore

Il primo passaggio nella progettazione del flusso del programma consiste nell'organizzare il codice stabilendo un insieme di regole che aiutino a creare un progetto, o struttura, dell'applicazione. La manutenzione, il debug e la correzione dei bug saranno più semplici perché il codice si trova in una posizione logica. Dopo aver svolto le basi, puoi scegliere un approccio per implementare la logica della tua applicazione.

I modelli di progettazione dovrebbero svolgere un ruolo importante nella progettazione del controllo del flusso del programma. Nel corso degli anni è stato scritto molto codice e sono state progettate molte soluzioni per problemi ricorrenti. Queste soluzioni sono disposte in modelli di progettazione. L'applicazione di un modello di progettazione a un problema di progettazione software comune ti aiuterà a creare soluzioni facilmente riconoscibili e implementabili dai tuoi colleghi. Problemi unici richiederanno comunque soluzioni uniche, ma puoi utilizzare i modelli di progettazione per guidarti nella loro risoluzione.

Creazione del progetto

strati

Il primo passo è considerare i livelli logici. Si noti che i livelli non sono la stessa cosa dei livelli, spesso confusi o addirittura considerati uguali.

strati contro strati

I livelli riguardano la creazione di limiti nel codice. Il livello superiore può avere riferimenti al codice nei livelli inferiori, ma un livello non può mai avere un riferimento al codice in un livello superiore. I livelli si riferiscono alla distribuzione fisica dei livelli su più computer. Ad esempio, in un'applicazione a tre livelli, l'interfaccia utente è progettata per essere eseguita su un computer desktop, la logica dell'applicazione è progettata per essere eseguita su un server delle applicazioni e il database viene eseguito su un server di database. strato può essere costituito da più strati.

Figura 8-1: Organizzazione di base a tre livelli

I livelli si riferiscono ai livelli di astrazione. I livelli mostrati nella Figura 8-1 valgono per la maggior parte delle applicazioni. Questi livelli sono anche indicati come i tre strati principali e possono avere vari altri nomi. Di norma, il codice nel livello di presentazione può chiamare i servizi nel livello della logica dell'applicazione, ma il livello della logica dell'applicazione non deve chiamare il metodo nel livello della presentazione. Il livello di presentazione non dovrebbe mai chiamare direttamente il livello di accesso ai dati, in quanto ciò aggirerebbe le responsabilità implementate dal livello della logica dell'applicazione. Il livello di accesso ai dati non dovrebbe mai chiamare il livello della logica dell'applicazione.

I livelli sono solo un'astrazione e probabilmente il modo più semplice per implementare i livelli è creare cartelle nel progetto e aggiungere codice alla cartella appropriata. Un approccio più utile sarebbe quello di posizionare ogni livello in un progetto separato, creando così assiemi separati. Il vantaggio di inserire la logica dell'applicazione in un assembly di libreria è che ti consentirà di creare unit test, utilizzando Microsoft Visual Studio o NUnit, per testare la logica. Crea inoltre flessibilità nella scelta di dove distribuire ogni livello.

Strati fisici

In un'applicazione aziendale, ti aspetteresti di avere più client per la stessa logica. In effetti, ciò che rende un'applicazione un'applicazione aziendale è che verrà distribuita su tre livelli: client, server delle applicazioni e server del database. L'applicazione Microsoft Office Access creata dal reparto vendite della società, sebbene molto importante per il reparto vendite, non è un'applicazione aziendale.

Si noti che la logica dell'applicazione ei livelli di accesso ai dati vengono spesso distribuiti insieme sul server delle applicazioni. Parte della progettazione del progetto consiste nella scelta se accedere al server delle applicazioni utilizzando servizi Web o .NET remoti. Qualunque sia la tua scelta, aggiungerai del codice per accedere facilmente ai servizi remoti nel livello di presentazione. Se si utilizzano i servizi Web per accedere ai servizi sul server delle applicazioni, Visual Studio .NET eseguirà il lavoro per l'utente e genererà il codice proxy, fornendo automaticamente un'implementazione del modello proxy remoto.

Aggiunta di motivi ai livelli

I tre livelli di base forniscono una panoramica di alto livello. Aggiungiamo alcuni modelli strutturali per creare una solida architettura aziendale. Il risultato è mostrato nella Figura 8-2.

Concentrati sul livello della logica dell'applicazione. La Figura 8-2 mostra che l'accesso alla logica dell'applicazione utilizza il modello di facciata. Una facciata è un oggetto che fornisce un'interfaccia semplificata a un corpo di codice più ampio, come una libreria di classi. Una facciata può ridurre le dipendenze del codice esterno dal funzionamento interno di una libreria perché la maggior parte del codice utilizza la facciata, consentendo così una maggiore flessibilità nello sviluppo del sistema. Per fare ciò, la facciata fornirà un'interfaccia a grana grossa a una raccolta di oggetti a grana fine.

flusso decisionale

Il controllo del flusso di programma, noto anche come flusso decisionale, riguarda il modo in cui progetti i servizi nel tuo livello logico applicativo o, come hai visto nel paragrafo precedente, come progetti i metodi nella tua facciata.

Ci sono due approcci per organizzare i tuoi servizi:

  • orientato all'azione
  • guidata dallo stato

Approccio orientato all'azione

Organizzando i servizi in base alle azioni dell'utente, stai implementando la logica dell'applicazione offrendo servizi, ognuno dei quali gestisce una richiesta specifica dal livello di presentazione. Questo è anche noto come modello di script di transazione. Questo approccio è popolare perché è semplice e sembra molto naturale. Esempi di metodi che seguono questo approccio sono BookStoreService.AddNewOrder(Order order) e BookStoreService.CancelOrder(int orderId).

La logica necessaria per eseguire l'azione è implementata in modo molto sequenziale all'interno del metodo, rendendo il codice molto leggibile ma anche più difficile da riutilizzare. L'utilizzo di modelli di progettazione aggiuntivi, come il modello del modulo tabella, può contribuire ad aumentare la riusabilità.

Approccio statale

È anche possibile implementare il flusso decisionale dell'applicazione in un modo molto più orientato allo stato. I servizi offerti dal server delle applicazioni sono di natura più generica, ad esempio BookStoreService.SaveOrder(Order order). Questo metodo esaminerà lo stato dell'ordine e deciderà se aggiungere un nuovo ordine o annullare un ordine esistente.

Progetti di strutture dati

Devi fare diverse scelte quando progetti le tue strutture di dati. La prima scelta è il meccanismo di archiviazione dei dati, la seconda è l'uso previsto dei dati e la terza sono i requisiti di versione. Esistono tre modi per esaminare i progetti della struttura dei dati:

  • I servizi offrono dati; i dati sono un riflesso del database relazionale.
  • I dati devono essere mappati agli oggetti e i servizi forniscono l'accesso agli oggetti.
  • I dati offerti dai servizi devono essere basati su schemi.

La scelta di uno dei tre come base per la struttura del flusso di dati dovrebbe essere effettuata in una fase iniziale del processo di progettazione. Molte aziende hanno una linea guida aziendale che impone una delle tre opzioni su tutti i progetti, ma ove possibile, dovresti rivalutare le opzioni per ciascun progetto, scegliendo l'approccio ottimale per il progetto in questione.

Scelta di un motore di archiviazione dei dati

Quando progetti la tua applicazione, dovrai senza dubbio progettare una sorta di archivio dati. Sono disponibili i seguenti archivi e forme di archiviazione dei dati:

  • Documentazione
  • file app.config
  • file xml
  • file di testo normale
  • Banca dati
  • accodamento messaggi

Ogni negozio ha le sue caratteristiche uniche e può essere personalizzato in base a requisiti specifici.

Progettazione del flusso di dati

Flusso di dati tramite ADO.NET

Implementando servizi incentrati sui dati nel livello della logica dell'applicazione, progetterai il tuo flusso di dati utilizzando ADO.NET. La libreria di classi .NET Framework fornisce un'API (Application Programming Interface) completa per la manipolazione dei dati nel codice gestito. Denominata ADO.NET, l'API si trova nello spazio dei nomi System.Data. La completa separazione dei supporti dati e degli archivi dati è un'importante caratteristica di progettazione di ADO.NET. Classi come DataSet, DataTable e DataRow sono progettate per archiviare i dati ma non conservano alcuna conoscenza della provenienza dei dati. Sono considerati indipendenti dall'origine dati. Un set separato di classi, ad esempio SqlConnection, SqlDataAdapter e SqlCommand, si occupa della connessione a un'origine dati, del recupero dei dati e del popolamento di DataSet, DataTable e DataRow. Queste classi si trovano in spazi dei nomi secondari come System.Data.Sql, System.Data.OleDB, System.Data.Oracle e così via. A seconda dell'origine dati a cui desideri connetterti, puoi utilizzare le classi nello spazio dei nomi corretto e, a seconda dell'ambito del prodotto che stai utilizzando, scoprirai che queste classi offrono più o meno funzionalità.

Poiché il DataSet non è connesso all'origine dati, può essere utilizzato con successo per gestire il flusso di dati in un'applicazione. La Figura 8-5 mostra il flusso di dati durante questa operazione.

Diamo un'occhiata a questo progetto e immaginiamo che qualcuno sia entrato nella tua libreria e abbia ordinato tre libri. Il livello di presentazione gestiva lo stato del carrello. Il cliente è pronto per effettuare l'ordine e ha fornito tutti i dati necessari. Sceglie di inviare l'ordine. La pagina web trasforma tutti i dati in un DataSet contenente due DataTable, una per l'ordine e una per l'ordine; inserisce un DataRow per l'ordine; e inserisce tre DataRow per le righe dell'ordine. La pagina Web quindi mostra nuovamente questi dati all'utente, associando i controlli dei dati al set di dati e chiedendo Sei sicuro? L'utente conferma la richiesta e questa viene inviata al livello logico dell'applicazione. Il livello della logica dell'applicazione controlla il DataSet per vedere se tutti i campi obbligatori hanno un valore ed esegue un controllo per vedere se l'utente ha più di 1000 US$. 00 sulle bollette in sospeso. Se tutto va bene, il DataSet viene passato al livello di accesso ai dati, che si connette al database e genera istruzioni di inserimento dalle informazioni del DataSet.

L'uso del DataSet in questo modo è un modo rapido ed efficiente per creare un'applicazione e utilizzare la potenza della libreria di classi Framework e la capacità di ASP.NET di associare i dati a vari controlli come GridView rispetto a un DataSet. Invece di utilizzare semplici oggetti DataSet, è possibile utilizzare oggetti DataSet tipizzati e migliorare l'esperienza di codifica implementando il codice nel livello di presentazione e nel livello della logica dell'applicazione. Il vantaggio di questo approccio è anche lo svantaggio dell'approccio. Piccole modifiche al modello di dati non comportano necessariamente che molti metodi debbano modificare le proprie firme. Quindi, in termini di manutenzione, funziona davvero bene. Se ricordi che il livello di presentazione non è necessariamente un'interfaccia utente, può anche essere un servizio web. E se modifichi la definizione del DataSet, forse perché stai rinominando un campo nel database, stai modificando il contratto a cui si iscrive il servizio web. Come puoi immaginare, questo può portare ad alcuni problemi significativi. Questo scenario funziona bene se il livello di presentazione è solo un'interfaccia utente, ma per le interfacce a sistemi o componenti esterni, ti consigliamo di nascondere il funzionamento interno della tua applicazione e trasformare i dati in qualcosa di diverso da un clone diretto del tuo modello di dati e vorrai creare Data Transfer Objects (DTO).

Flusso di dati utilizzando la mappatura relazionale degli oggetti

Il flusso di dati che utilizza ADO.NET è un approccio molto incentrato sui dati per la gestione del flusso di dati. I dati e la logica sono discreti. L'altra estremità dello spettro sta adottando un approccio più orientato agli oggetti. Qui, le classi vengono create per raggruppare dati e comportamento. L'obiettivo è definire classi che imitano i dati e il comportamento trovati nel dominio aziendale per il quale è stata creata l'applicazione. Il risultato è spesso indicato come un oggetto di business. L'insieme di oggetti di business che compongono l'applicazione è chiamato modello di dominio. Alcuni sviluppatori affermano che un modello di dominio ricco è migliore per progettare una logica più complessa. È difficile provare o smentire una simile affermazione. Sappi solo che hai una scelta e sta a te farla.

La Figura 8-6 mostra un flusso di dati simile alla Figura 8-5 , tranne per il fatto che ora hai aggiunto il livello di mappatura relazionale degli oggetti e sostituito gli oggetti DataSet con diversi supporti dati.

Ora fai lo stesso passo dopo passo di prima; immagina che qualcuno si sia collegato alla tua libreria e abbia ordinato tre libri. Il livello di presentazione gestiva lo stato del carrello. Il cliente è pronto per effettuare l'ordine e ha fornito tutti i dati necessari. Sceglie di inviare l'ordine. La pagina Web trasforma tutti i dati in un DTO, contenente i dati per un ordine e con tre righe di ordine, creando gli oggetti secondo necessità. La pagina Web mostra nuovamente questi dati all'utente, il data binding controlla il DTO utilizzando ObjectDataSource in ASP.NET 2.0 e chiede Sei sicuro? L'utente conferma la scelta e il DTO viene inviato al livello logico dell'applicazione. Il livello della logica dell'applicazione trasforma il DTO in un oggetto business di tipo Order con una proprietà per contenere tre oggetti OrderLine. Il metodo dell'ordine. Validate() viene richiamato per convalidare l'ordine e verificare che tutti i campi obbligatori abbiano un valore e viene effettuato un controllo per identificare se l'utente ha più di R$ 1.000,00 in ricevute in sospeso. Per fare ciò, l'ordine chiamerà Order.Customer.GetOutstandingBills(). Se tutto va bene, viene chiamato il metodo Order.Save(). La richiesta passerà attraverso il livello di mappatura relazionale dell'oggetto, in cui la richiesta e le righe della richiesta vengono mappate a un DataTable in un DataSet e il DataSet viene passato al livello di accesso ai dati, che si connette al database e genera istruzioni di inserimento da le informazioni nel DataSet. Ci sono, ovviamente, molti modi in cui può verificarsi la mappatura relazionale tra oggetti, ma non tutti includeranno la trasformazione in un DataSet. Alcuni creeranno direttamente l'istruzione insert ma continueranno a utilizzare il livello di accesso ai dati per eseguire tale istruzione.

Come puoi vedere, avvengono alcune trasformazioni. L'uso di DTO è necessario perché un oggetto di business implementa il comportamento e il comportamento è soggetto a modifiche. Per ridurre al minimo l'impatto di queste modifiche sul livello di presentazione, è necessario trasformare i dati dall'oggetto di business in un oggetto di trasferimento dati. In Java, l'oggetto di trasferimento dei dati viene spesso definito oggetto valore.

Un grande vantaggio di lavorare con gli oggetti di business è che aiuta davvero a organizzare il codice. Se guardi indietro a un pezzo di logica complessa, di solito è molto leggibile perché c'è pochissimo codice idraulico. Lo svantaggio è che la maggior parte degli archivi di dati è ancora relazionale e la mappatura degli oggetti di business ai dati relazionali può diventare piuttosto complessa.

servizi basati su schemi

Hai appena visto due opposti quando si tratta di gestire il flusso di dati. Sono possibili molte varianti. Una variante comune è la variante in cui un set di dati viene utilizzato come supporto dati di base dell'interfaccia utente per l'archiviazione dei dati, ma vengono utilizzati schemi separati (DTO) per i servizi Web richiamati da altri sistemi. Il livello dell'applicazione trasforma i dati relazionali in uno schema predefinito. Il vantaggio principale di ciò è che qualsiasi applicazione che fa riferimento al servizio non dipende da alcun tipo di implementazione interna del componente. Ciò consente una maggiore flessibilità nel controllo delle versioni, compatibilità con le versioni precedenti delle interfacce e la possibilità di modificare l'implementazione del componente senza modificare l'interfaccia del servizio.

Naturalmente, è possibile utilizzare oggetti di business nell'applicazione Web e ignorare la trasformazione DTO, ma questo di solito funziona bene solo se la logica dell'applicazione viene implementata insieme all'applicazione Web. Ricorda che per chiamare Order.Save() avrai bisogno di una connessione al database. Se questo è desiderabile dipende da te e probabilmente dal tuo direttore della sicurezza.