1. Statico contro istanza
Penso che ci siano linee guida molto chiare su ciò che è buono design OO e cosa no. Il
il problema è che la blogosfera rende difficile separare il buono dal brutto e il cattivo. Puoi trovare alcuni tipi di riferimento che supportano anche le peggiori pratiche a cui puoi pensare.
E la peggiore pratica che mi viene in mente è Global State, inclusa la statica che hai menzionato e il singleton preferito di tutti. Alcuni estratti dall'articolo di Misko Hevery classico sull'argomento .
To really understand the dependencies, developers must read every line of code. It causes Spooky Action at a Distance: when running test suites, global state mutated in one test can cause a subsequent or parallel test to fail unexpectedly. Break the static dependency using manual or Guice dependency injection.
Spooky Action at a Distance is when we run one thing that we believe is isolated (since we did not pass any references in) but unexpected interactions and state changes happen in distant locations of the system which we did not tell the object about. This can only happen via global state.
You may not have thought of it this way before, but whenever you use static state, you’re creating secret communication channels and not making them clear in the API. Spooky Action at a Distance forces developers to read every line of code to understand the potential interactions, lowers developer productivity, and confuses new team members.
Ciò a cui si riduce è che non si dovrebbero fornire riferimenti statici a qualcosa che ha una sorta di stato memorizzato. L'unico posto in cui utilizzo la statistica è per le costanti numerate e ho anche dei dubbi in proposito.
2. Metodi con parametri di input e valori di ritorno rispetto a metodi con none
La cosa che devi realizzare è che i metodi che non hanno parametri di input e nessun parametro di output sono praticamente garantiti per operare su una sorta di stato memorizzato internamente (altrimenti, cosa stanno facendo?). Ci sono intere lingue basate sull'idea di evitare lo stato memorizzato.
Ogni volta che hai lo stato memorizzato, hai la possibilità di effetti collaterali, quindi assicurati di utilizzarlo sempre in modo consapevole. Ciò implica che dovresti preferire funzioni con input e / o output definiti.
E, in effetti, le funzioni che hanno input e output definiti sono molto più facili da testare - non devi eseguire una funzione qui e andare a guardare là per vedere cosa è successo, e non devi impostare una proprietà da qualche altra parte prima di eseguire la funzione in prova.
Puoi anche tranquillamente usare questo tipo di funzione come statica. Tuttavia, non lo farei, perché se in seguito avrei voluto utilizzare un'implementazione leggermente diversa di quella funzione da qualche parte, anziché fornire un'istanza diversa con la nuova implementazione, non sono in grado di sostituire la funzionalità.
3. Sovrapposizione e Distinzione
Non capisco la domanda. Quale sarebbe il vantaggio in 2 metodi di sovrapposizione?
4. Privato vs. Pubblico
Non esporre oggetti che non è necessario esporre. Tuttavia, non sono nemmeno un grande fan del privato. Non sono uno sviluppatore C #, ma uno sviluppatore di ActionScript. Ho passato molto tempo nel codice Flex Framework di Adobe, che è stato scritto intorno al 2007. E hanno fatto delle scelte davvero sbagliate su cosa rendere privato, il che rende quasi un incubo cercare di estendere le loro Classi.
Quindi, a meno che non pensi di essere un architetto migliore degli sviluppatori Adobe nel 2007 (dalla tua domanda, direi che hai ancora qualche anno prima di avere la possibilità di presentare tale richiesta), probabilmente vorresti solo predefinito su protetto.
Ci sono alcuni problemi con i tuoi esempi di codice che indicano che non sono ben architettati, quindi non è possibile selezionare A o B.
Per prima cosa, probabilmente dovresti separare la creazione dell'oggetto da il suo uso . Quindi di solito non avresti il tuo new XMLReader()
proprio accanto a dove viene utilizzato.
Inoltre, come dice @djna, dovresti incapsulare i metodi utilizzati nel tuo XML Reader, quindi la tua API (esempio di istanza) potrebbe essere semplificata in:
_document Document = reader.read(info);
Non so come funzioni C #, ma dal momento che ho lavorato con un certo numero di tecnologie web, sarei sospettoso che non saresti sempre in grado di restituire immediatamente un documento XML (tranne forse come una promessa o futuro tipo oggetto), ma non posso darti consigli su come gestire un carico asincrono in C #.
Si noti che con questo approccio, è possibile creare diverse implementazioni che possono assumere un parametro che indichi dove / cosa leggere e restituire un oggetto XML e scambiarle in base alle esigenze del progetto. Ad esempio, potresti leggere direttamente da un database, da un negozio locale o, come nel tuo esempio originale, da un URL. Non puoi farlo se usi un metodo statico.