...all the claims that have been made about Object Orientedness (for
lack of a better term) being great at reusing code have been flat out
lies
Forse il motivo migliore per cui le persone pensano che OOP produca codice che è difficile da riutilizzare è che non usano nemmeno le metodologie OO! Solo perché usi un linguaggio OO significa che stai applicando le tecniche OO appropriate.
Penso che Telastyn faccia un buon punto sulle dipendenze, quindi vorrei proporre una soluzione a questo argomento.
Il riutilizzo del codice è in effetti una cosa difficile da ottenere in OOP. Richiede un'attenzione particolare all'architettura generale e alla stratificazione dell'applicazione. Se manchi di esperienza, puoi dedicare poco o nessun tempo a pensare a queste cose e inizi a codificare o puoi farlo perché è solo il modo più semplice. Quindi si finisce con classi strettamente accoppiate che non sono moduli e non possono essere estratte e riutilizzate.
Puntare a classi di moduli piccoli e accoppiati liberamente è uno dei modi migliori per ottenere il riutilizzo del codice. Dependency Injection è un ottimo strumento per fare ciò (mi riferisco al pattern, non a tutti i framework DI / IOC).
Ecco un esempio per dimostrarlo
Hard-Coded
class WebScraper
{
Database Db = new Database();
public string Scrape(string url)
{
string content = WebClient.DownloadString(url);
Db.Save(content);
return content;
}
}
Iniezione di dipendenza
class WebScraperPro
{
IStorage Storage;
public WebScraperPro(IStorage storage)
{
Storage = storage;
}
public string Scrape(string url)
{
string content = WebClient.DownloadString(url);
storage.Save(content);
return content;
}
}
Dopo aver scritto la prima lezione ho codificato il mio codice di database direttamente nella classe. Ciò rende difficile il riutilizzo, perché se non si dispone di una connessione di rete per raggiungere il server di database, cosa succede se non voglio memorizzarlo in un database? Se volessi solo raschiare il sito web, dovrei scrivere una nuova classe anche se tutte le funzionalità sarebbero uguali eccetto per la persistenza.
D'altra parte quando usiamo Dependency Injection abbiamo disaccoppiare il database dalla logica di business. Posso passare un oggetto TextStorage
che lo scrive in un file di testo solo se non ho accesso alla rete, oppure posso passare un oggetto NoStorage
se non voglio memorizzarlo da nessuna parte. Mi permette di riutilizzarlo più facilmente. Notare anche che ora abbiamo separato il livello Logica dal nostro livello dati. Questa è la stessa ragione per cui non vogliamo inserire il codice UI nel livello Logica.
Questo è solo un esempio forzato dalla parte superiore della mia testa, potresti spostare la persistenza a un livello più alto, ma dovrebbe aiutare a cogliere il concetto di rimozione delle dipendenze hard-coded.
Quando le persone usano classi statiche ovunque non si rendono nemmeno conto di legare il loro codice a queste dipendenze. Quando si assegnano classi concrete all'interno di altre classi si sta facendo la stessa cosa. Programmare un'interfaccia e rimuovere le dipendenze hard-coded è un grande passo avanti nella scrittura di codice che è riutilizzabile. Trovo anche che scrivere su un'interfaccia mi faccia pensare più duramente alla responsabilità della classe e finisco per scrivere classi più piccole che seguono il principio della responsabilità unica. Ciò rende tutto più modulare e più flessibile.
Non posso commentare sull'altro lato dello spettro se FP è migliore per il riutilizzo o meno perché non ho esperienza con FP, ma posso dire che è possibile scrivere codice altamente riutilizzabile in OOP se fatto correttamente.