La domanda presenta un falso dilemma. La corretta applicazione del principio YAGNI non è qualcosa di indipendente. È un aspetto del buon design. Ciascuno dei principi SOLID sono anche aspetti di un buon design. Non puoi sempre applicare completamente ogni principio in qualsiasi disciplina. I problemi del mondo reale mettono molte forze sul tuo codice e alcuni di questi spingono in direzioni opposte. I principi del design devono tener conto di tutti questi aspetti, ma nessuna manciata di principi può adattarsi a tutte le situazioni.
Ora diamo un'occhiata a ciascun principio con la comprensione che mentre a volte possono andare in direzioni diverse, non sono in alcun modo intrinsecamente in conflitto.
YAGNI è stato concepito per aiutare gli sviluppatori a evitare un particolare tipo di rilavorazione: ciò che deriva dalla costruzione della cosa sbagliata. Lo fa guidandoci ad evitare di prendere decisioni errate troppo presto sulla base di ipotesi o previsioni su ciò che pensiamo cambierà o sarà necessario in futuro. L'esperienza collettiva ci dice che quando lo facciamo, di solito abbiamo torto. Ad esempio, YAGNI ti direbbe di non creare un'interfaccia ai fini della riusabilità , a meno che tu non sappia al momento che hai bisogno di più implementatori. Allo stesso modo YAGNI direbbe di non creare uno "ScreenManager" per gestire il singolo modulo in un'applicazione a meno che tu non sappia in questo momento che avrai più di uno schermo.
Contrariamente a quanto pensano molte persone, SOLID non riguarda la riusabilità, la genericità o persino l'astrazione. SOLID ha lo scopo di aiutarti a scrivere codice preparato per il cambiamento , senza dire nulla su ciò che potrebbe essere quel cambiamento specifico. I cinque principi di SOLID creano una strategia per la costruzione di un codice flessibile senza essere eccessivamente generico e semplice senza essere ingenuo. La corretta applicazione del codice SOLID produce classi piccole e mirate con ruoli e confini ben definiti. Il risultato pratico è che per ogni modifica dei requisiti necessari, è necessario toccare un numero minimo di classi. Allo stesso modo, per qualsiasi modifica del codice, esiste una quantità minima di "ripple" attraverso altre classi.
Guardando la situazione di esempio che hai, vediamo cosa potrebbero dire YAGNI e SOLID. Stai prendendo in considerazione un'interfaccia di repository comune a causa del fatto che tutti i repository sembrano uguali dall'esterno. Ma il valore di un'interfaccia comune e generica è la capacità di utilizzare uno degli implementatori senza la necessità di sapere quale sia in particolare. A meno che non ci sia un posto nella tua app in cui ciò sia necessario o utile, YAGNI afferma di non farlo.
Ci sono 5 principi SOLIDI da guardare. S è la sola responsabilità. Questo non dice nulla sull'interfaccia, ma potrebbe dire qualcosa sulle tue lezioni concrete. Si potrebbe argomentare che la gestione dell'accesso ai dati stesso potrebbe essere ritenuta una responsabilità di una o più altre classi, mentre la responsabilità dei repository è quella di tradurre da un contesto implicito (CustomerRepository è un repository implicitamente per le entità del Cliente) in chiamate esplicite al API di accesso ai dati generalizzata che specifica il tipo di entità cliente.
O è aperto-chiuso. Si tratta principalmente di eredità. Si applicherebbe se si cercasse di derivare i propri repository da una base comune che implementa funzionalità comuni o se si prevede che deriveranno ulteriormente dai diversi repository. Ma non lo sei, quindi non lo è.
L è sostituibilità di Liskov. Ciò vale se si intendeva utilizzare i repository tramite l'interfaccia del repository comune. Pone restrizioni sull'interfaccia e le implementazioni per garantire coerenza ed evitare una gestione speciale per diversi impelementer. La ragione di ciò è che tale gestione speciale mina lo scopo di un'interfaccia. Potrebbe essere utile considerare questo principio, perché potrebbe avvertirti di non utilizzare l'interfaccia del repository comune. Ciò coincide con la guida di YAGNI.
Sono la segregazione dell'interfaccia. Questo può valere se si inizia ad aggiungere diverse operazioni di query ai propri repository. La segregazione dell'interfaccia si applica laddove è possibile dividere i membri di una classe in due sottoinsiemi in cui uno verrà utilizzato da determinati consumatori e l'altro da altri, ma nessun consumatore probabilmente utilizzerà entrambi i sottoinsiemi. La guida è creare due interfacce separate, anziché una comune. Nel tuo caso, è improbabile che il recupero e il salvataggio di singole istanze vengano consumati dallo stesso codice che farebbe una query generale, quindi potrebbe essere utile separarli in due interfacce.
D è Iniezione delle dipendenze. Qui torniamo allo stesso punto di S. Se hai separato il tuo consumo dell'API di accesso ai dati in un oggetto separato, questo principio dice che piuttosto che semplicemente rinnovare un'istanza di quell'oggetto, dovresti passarlo quando crei un repository. Ciò semplifica il controllo della durata del componente di accesso ai dati, aprendo la possibilità di condividere riferimenti ad esso tra i repository, senza dover seguire la strada per renderlo un singleton.
È importante notare che la maggior parte dei principi SOLID non si applica necessariamente in questa fase particolare dello sviluppo della tua app. Ad esempio, se è necessario interrompere l'accesso ai dati dipende da quanto sia complicato e se si desidera testare la logica del repository senza colpire il database. Sembra che sia improbabile (purtroppo, secondo me), quindi probabilmente non è necessario.
Quindi, dopo tutte queste considerazioni, scopriamo che YAGNI e SOLID forniscono effettivamente un consiglio comune, solido e immediatamente rilevante: probabilmente non è necessario creare un'interfaccia di repository generica comune.
Tutto questo attento pensiero è estremamente utile come esercizio di apprendimento. Mentre impari richiede tempo, ma col tempo sviluppi intuizione e diventa molto veloce. Saprai la cosa giusta da fare, ma non dovrai pensare a tutte queste parole a meno che qualcuno non ti chieda di spiegare il perché.