Come strutturare questo programma?

6

Sto lottando con il modo migliore per strutturare un programma che sto scrivendo perché il metodo che attualmente mi sembra molto goffo e ogni parte dipende molto dagli altri. Questo è ciò che il programma deve fare:

  1. Analizza un documento word per estrarre un elenco di contatti.
  2. Ottieni un elenco di contatti in un gruppo specificato dal mio account Google.
  3. Confronta i contatti del documento word con i contatti Google e:
  4. Aggiorna i contatti su Google con i dettagli del documento word o
  5. Crea un nuovo contatto su Google se non esiste o
  6. Elimina tutti i contatti su Google che non si trovano nel documento word.

Anch'io voglio

  • per avere una GUI per questo programma che è reattivo mentre tutto sta succedendo
  • mostra un'anteprima delle modifiche che i passaggi 4-6 effettueranno prima di eseguirle e consentire all'utente di rifiutare le modifiche (tutto o niente andrebbe bene per ora)

Modifica: tutto ciò che viene da qui in poi è ciò che ho attualmente fatto. L'ho aggiunto in modo che potesse essere fornito un consiglio specifico per il refactoring se ciò fosse ritenuto necessario. Se hai un modo in cui posso strutturare questo programma, puoi quasi sempre saltare il resto.

Ho già iniziato, quindi permettimi di spiegare come ho scritto il codice finora. Il programma è scritto in C #.

  1. L'analisi del documento word per ottenere un elenco di contatti è in una classe chiamata WordDocumentParser . Ha un costruttore che prende il percorso del documento word e un metodo GetContacts che esegue tutto l'analisi e restituisce un elenco di contatti. Per quello che vale, sto usando COM per gestire l'analisi.

  2. I passaggi da 2 a 6 partendo da una nuova classe chiamata GoogleContactsMaintainer con un costruttore che prende l'elenco dei contatti dal documento word, un paio di gruppi importanti su Google e un ContactsRequest che è utilizzato per recuperare / aggiornare / salvare / eliminare i contatti su Google. La prima cosa che fa questa classe è ottenere i contatti da Google e abbinarli ai contatti del documento word. Il contatto Google corrispondente viene salvato in una proprietà sulla parola documento contatto.

  3. Quindi eseguo un'anteprima che rappresenta i prossimi 3 passaggi.

  4. Inizio con l'aggiornamento dei contatti che sono stati abbinati dal documento word ai contatti di Google. Creo un ContactUpdater che aggiorna il contatto Google corrispondente ma non conferma le modifiche. Aggiunge anche a un elenco di stringhe tutte le modifiche che sono state apportate e imposta una proprietà booleana sul contatto per dire che è stato aggiornato.

  5. Il prossimo è la creazione di nuovi contatti Google per quei contatti di documenti di testo che non sono stati abbinati a un contatto di Google. Questo viene fatto in una classe ContactCreator che crea un contatto Google, lo imposta sulla parola contatto documento e imposta un flag su quel contatto per indicare che si tratta di un nuovo contatto. Il nuovo contatto non viene salvato.

  6. L'ultimo è eliminare tutti i contatti Google che non sono stati abbinati a un contatto dal documento word. Per fare questo, trovo i contatti e li aggiungo a un elenco con una descrizione che dice che saranno eliminati.

  7. Al momento, visualizzo queste modifiche all'utente e le aggiorno immediatamente (spiegherò perché l'utente non può fermarlo in un minuto). Questo viene fatto nelle seguenti tre fasi.

  8. Aggiornamento: trova tutti i contatti dal documento word che hanno il set di proprietà HasBeenUpdated , costruisci un nuovo ContactUpdater e conferma le modifiche.

  9. Crea: trova tutti i contatti dal documento word che hanno il set di proprietà NewContact , costruisci un nuovo ContactCreator e inserisci il nuovo contatto Google.

  10. Elimina: trova tutti i contatti Google che non sono stati abbinati a un contatto dal documento word e li elimina da Google.

Nel tentativo di mantenere la mia GUI reattiva mentre tutto questo è in corso, ho creato una classe MaintainContactsWorker che sottoclasse BackgroundWorker e chiama tutti i 10 passi precedenti dal metodo OnDoWork . Questo è il motivo per cui non sono in grado di chiedere all'utente se vogliono confermare o meno le modifiche.

Per me, tutto sembra orribilmente interconnesso e completamente non testabile, quindi spero che tu possa indicare le cose che dovrei fare per rompere le dipendenze e rendere il mio codice più gestibile e verificabile.

Da quando ho scritto questo post, una cosa che sento di dover avere è un repository che gestirà le operazioni CRUD che sto eseguendo sui contatti di Google. Questo sembra un buon punto di partenza?

Grazie per tutti i suggerimenti che puoi offrire, spero di essermi spiegato abbastanza bene.

    
posta Stu 31.12.2011 - 17:19
fonte

2 risposte

5

Il tuo processo:

  • Analizza un documento word per estrarre un elenco di contatti.
  • Ottieni un elenco di contatti in un gruppo specificato dal mio account Google.
  • Confronta i contatti del documento word con i contatti Google e:
  • Aggiorna i contatti su Google con i dettagli del documento word o
  • Crea un nuovo contatto su Google se non esiste o
  • Elimina tutti i contatti su Google che non si trovano nel documento word.

Una possibile struttura:

WordDocParser docParser = new WordDocParser(path);
IList<Contact> wordContacts = docParser.ParseContacts();

GoogleContactsManager googleManager = new GoogleContactsManager(accountInfo);
IList<Contact> googleContacts = googleManager.GetContacts();

ContactComparer comparer = new ContactComparer();
IList<ContactUpdateAction> updateActions = 
    comparer.Compare(wordContacts, googleContacts);

//user can edit/alter update actions here

googleContacts.UpdateContacts(updateActions);

Per una GUI reattiva, mostrare quale fase sta accadendo con una barra di avanzamento dovrebbe essere sufficiente fino al punto in cui l'utente può vedere / modificare le azioni di aggiornamento. È possibile utilizzare un thread background / worker per ogni passaggio, con un pulsante per consentire all'utente di annullare il processo. Il thread in background può aggiornare un flag (Mutex o simile) quando viene fatto per segnalare l'avvio del prossimo passaggio in background.

Ogni UpdateAction può specificare se aggiungere, eliminare o modificare le informazioni di contatto. Queste informazioni possono essere visualizzate all'utente prima di apportare modifiche all'account Google (almeno in teoria!) Quando l'utente è soddisfatto, può fare clic sul pulsante Conferma modifiche per eseguire l'ultimo passaggio o su Annulla.

    
risposta data 31.12.2011 - 22:14
fonte
0

(Sono un programmatore Java, non C #.)

Avrei una classe ContactSet , con sottoclassi GoogleContactSet e WordFileContactSet . L'interfaccia avrebbe 4 metodi: iterator() , add(Contact c) , remove(Contact c) e update(Contact c) . Internamente, ContactSet memorizzerebbe Set (in Java, ma suppongo che C # abbia un insieme non ordinato equivalente). Il metodo iterator() restituisce semplicemente l'iteratore del% co_de sottostante, e lo stesso per Set e add(...) . I contatti di Google leggono nel creatore remove(...) e quelli del file sono letti nel creatore new GoogleContactSet(googleID) .

Vorrei anche aggiungere un quinto metodo in new WordFileContactSet(fileName) : ContactSet che restituisce un findExtraneous(ContactSet d) di tutti ContactSet s che si trovano nel set corrente, ma non in Contact . Questo sarebbe implementato come doppio ciclo sugli iteratori di d e this .

Sembra abbastanza facile escogitare alcuni test per le suddette classi e metodi.

d verrebbe chiamato all'inizio del codice GUI. Quindi disponi di un codice che cerca la conferma dell'utente e inserisce findExtraneous(...) s che verrà aggiunta / rimossa / aggiornata in 3% corrispondenti di Contact . Infine, chiami ContactSet o googleContactSet.add(someContact) o remove sul set corrispondente di contatti. Dovrai impostarlo in alcuni metodi nella GUI C # (non ho familiarità con quella parte).

Non hai bisogno delle classi update , ContactUpdater ; sarebbe eccessivo OO.

Il test del codice GUI è sempre difficile, se non impossibile.

EDIT: sopra a ContactRemover , contactSet.add(Contact c) e put(Contact c) , potresti aggiungere 3 metodi corrispondenti che accettano un set come argomento, ad es. %codice%. Ma non aggiungerei un metodo che restituisca direttamente il% co_de sottostante anziché l'iteratore, poiché remove(Contact c) potrebbe quindi essere manipolato direttamente da chiunque.

    
risposta data 01.01.2012 - 18:41
fonte

Leggi altre domande sui tag