Applica il Refactoring di singola responsabilità nell'app form

0

Davvero non capisco l'SRP applicato a un progetto "reale" (davvero non così reale ma può aiutarmi a conoscere il tuo approccio)

Trovo molto difficile dividere e assegnare responsabilità alle mie classi.

Così ho pubblicato un esempio in pseudo codice, e spero che qualcuno possa illuminarmi.

Ho un semplice modulo di Windows, INPUT: un file excel, una stringa iniziale, una stringa finale OUTPUT: una griglia di risultati, che corrisponde a tutte le parole di sottostringa dalla stringa iniziale alla fine dall'elenco excel.

Il modulo ha un pulsante che carica l'input, cerca tutte le parole che soddisfano alcuni criteri e associa i risultati in una griglia.

Quello che dovrei sapere è il tuo approccio nel rifattorizzare questo semplice pezzo di codice.

private void load() 
{
  Open a dialog file ;
  Get result of open dialog file as a filename ;
  If (filename exists and it is valid) {
      Call Excel libraries to convert the excel data into a gridview ;
      Fill the datagridview ;
      Release the inbuilt excel resources ;
 };

private void process() 
{  
  If (some validation on start and end string format) {
      Construct a regex expression filter that match with start and end string;
      Create a new list with the matched results;
      Bind result data into a new datagridview;
   }
};

Qual è l'approccio del tuo refactoring a questo pezzo di codice?

    
posta Fadelast 26.11.2018 - 11:05
fonte

2 risposte

0

Non sei sicuro del motivo per cui hai problemi a vedere lo split

//responsibility : contain the data from a spreadsheet
public class SpreadSheet
{
    public Row[] Rows {get;set;}
}

//responsibility : load spreadsheets from a data source
public class SpreadSheetLoader : ISpreadSheetLoader
{
    public SpreadSheet Load(string filename)
}

//responsibility : search a spreadsheet and return the results
public class SpreadSheetSearcher
{
    public SearchResult SearchSpreadSheet(SpreadSheet spreadsheet, string searchstring);
}

//responsibility :: join the view (form) to the models (business object defined above)
public class myApp
{
    LoadButtonClick()
    {
         this.spreadSheet = this.spreadSheetLoader.Load(this.txt_filename)
         this.spreadSheetDataGrid.Load(this.spreadSheet)
    }
    SearchButtonClick()
    {
         this.searchResults = this.spreadSheetSearcher(this.spreadSheet, this.txt_searchstring)
         this.resultDatagrid.Load(this.searchResults)
    }
}
    
risposta data 26.11.2018 - 12:38
fonte
0

Commento preliminare

Il principio di responsabilità singola si applica a classi e moduli. Non si tratta di funzionalità, ma di motivi per cambiare (come spiegato nell'articolo collegato da Uncle Bob). In altre parole, non è tanto la responsabilità di della classe, quanto la responsabilità di ciò che fa la classe.

La progettazione funziona bene

La tua domanda riguarda più le funzioni e il principio fai-da-una-cosa-e-fai-bene :

  • nella funzione di caricamento si fanno due cose molto diverse: scoprire cosa caricare (interazione dell'utente in attesa di utente) e caricare i dati (operazione tecnica che può essere eseguita in background senza attendere).
  • nella funzione del tuo processo, fai anche due cose diverse. Il primo è un calcolo complesso (il nucleo dell'elaborazione) il secondo è l'output del risultato.

La chiave qui è la manutenibilità e il riutilizzo:

  • E se un giorno decidessi di caricare un file predefinito all'avvio, in silenzio, senza disturbare l'utente? Con la tua struttura, dovresti riscrivere una seconda funzione di caricamento, quindi non utilizzare più DRY. E avresti quindi due funzioni da mantenere, se la struttura dei dati dovesse cambiare.
  • e se un giorno avresti eseguito la migrazione della tua app a Windows 25 con un'API completamente rinnovata (ad esempio le finestre di dialogo con comando vocale che sostituiscono i dialoghi dello schermo)? Con la tua struttura, gli specialisti dell'interfaccia utente dovrebbero passare attraverso due funzioni eterogenee, cercando di capire cos'è l'interfaccia utente e cosa rimane invariato.

Ecco perché fare una cosa è così importante. È un modo per trarre vantaggio dalla separazione delle preoccupazioni.

Ma come possiamo ottenere qualcosa di complesso, se le funzioni fanno una cosa?

D-O-T ha un altro principio chiave: avere un solo livello di astrazione in ogni funzione. Entrambi i principi devono essere considerati insieme.

Questo significa che puoi avere una funzione che fa una cosa complessa come ad esempio "caricare un file scelto dall'utente". Ma questa cosa complessa sarebbe scomposta in due cose meno complesse a un livello più basso di astrazione, chiedendo (UI) e caricando (file di lettura). Ciascuno sarebbe quindi implementato in una funzione di livello inferiore che fa-one-thing-and-do-it-well.

    
risposta data 26.11.2018 - 13:17
fonte

Leggi altre domande sui tag