Cos'è più importante? SOLIDO o BACIO?

5

Cos'è più importante? SOLIDO o BACIO?

Per essere coerente con SOLID, dovrei inserire le classi Decorator e Footer e creare interfacce per loro.

public class HelloService {
   String name;
   HelloService(String name){
      this.name = name;
   }
   public String getHello() {
      Decorator decorator = new Decorator();

      String full = decorator.bar
              + this.name 
              + Footer.add(this.name);

      return full;
   }
}

public class Decorator {
    public String bar() {
        return "Some";
    }
}

public class Footer {
    public static String add(String name) {
        if (name.length() > 10) {
            return "A";
        } else {
            return "B";
        }
    }
}

Non sarebbe un'esagerazione?

Il mio esempio è semplice, ma se fosse complesso, cosa dovrei fare? Se uso altre classi in classe solo in un posto, dovrei anche iniettarle?

Come posso migliorare le mie lezioni in modo che siano conformi alle regole e leggibili per tutti?

    
posta cimlihor 05.03.2018 - 22:18
fonte

5 risposte

15

TLDR;

Né è "più importante". Gli sviluppatori non servono i principi; i principi servono agli sviluppatori. Applicali nel modo e nella misura in cui raggiungono i tuoi obiettivi e ti aiutano a consegnare

Alcuni punti di calibrazione:

  • La D in SOLID è non Iniezione di dipendenza ; è Inversione di dipendenza . La dipendenza Iniezione sembra essere una soluzione importante per < em> invertendo le dipendenze . L'aspetto importante di questo D semplifica il cambiamento delle cose che potrebbero effettivamente cambiare.

  • KISS ricorda agli sviluppatori di mantenere le cose semplici e "stupide" come . non suggerisce di rendere le cose più semplici di quanto non siano in realtà. Non impone il sacrificio su manutenibilità, estensibilità o funzionalità. Né ti richiede di tank il ROI della tua attività per soddisfare il senso di "semplicità" o "eleganza" dello sviluppatore.

  • I principi del software sono pragmatici. Né il codice semplice, né il codice con dipendenze invertite, né il codice test-driven sono intrinsecamente "migliori". Il buon codice ha uno scopo. I principi di codifica sono applicabili solo nella misura in cui servono allo scopo del codice.

  • Devi capire lo scopo del tuo codice e i principi. Se non comprendi lo scopo del tuo codice (compresi gli "obiettivi" dell'azienda come la manutenibilità ), i principi faranno poco per aiutare. E, se non capisci i principi, non puoi applicarli comunque.

In altre parole, applica il POAP , che farò ora spudoratamente cito dal mio singolo blog "blog" ...

Principles, patterns, and practices are not final purposes. The good and proper application of each is therefore inspired and constrained by a superior, more final purpose.

You need to understand why you're doing what you're doing!

(The POAP is not exempt from the POAP.)

Sfortunatamente, questa roba è difficile da insegnare - se è insegnabile a tutti. Se non hai un mentore esperto di domini, scovalo nel miglior modo possibile. E, la prossima volta che devi toccare questo codice, chiediti cosa ha funzionato e cosa no?

    
risposta data 06.03.2018 - 00:35
fonte
7

La cosa più importante è che il tuo programma funzioni e renda felici gli utenti fornendo i risultati attesi. Ma ciò che li ha resi felici ieri, potrebbe non essere più sufficiente a renderli felici domani.

Questo è il motivo per cui i due principi non sono in competizione ma sono intrecciati:

  • KISS può aiutare a concentrarsi sui risultati iniziali senza distrazioni, elaborando una soluzione semplice. Come bonus extra, evitando la complessità, KISS riduce il potenziale di bug.

  • Tuttavia, nella vita reale gli utenti tendono a cambiare idea e ad aggiungere requisiti nuovi o dimenticati durante lo sviluppo, senza parlare successivamente nei molti anni in cui il sistema verrà utilizzato. Molto spesso, il tuo codice deve evolversi prima ancora che sia finito. Sembra che SOLID aiuti a realizzare un design robusto che può evolvere molto più facilmente.

  • A volte SOLID e KISS potrebbero persino riferirsi alla stessa soluzione

La sfida principale nell'arte dello sviluppo del software è bilanciare i due. Mantenerlo il più semplice possibile, ma non simulabile e, allo stesso tempo, renderlo SOLIDO senza aggiungere molto peso. In altre parole, non applicare i principi alla cieca.

P.S: il tuo programma non è né KISS né SOLID: sarebbe molto più semplice avere bar() e add() come membri di HelloService . Quindi questa soluzione è già troppo ingegnerizzata.

PS2: ma se pensi che Decorator e Footer meritino l'incapsulamento, sarebbe molto più sicuro per il futuro disaccoppiare le classi con una DI corretta, in modo che tu possa avere diversi Decoratori e Piè di pagina diversi (ad esempio per ottimizzare il layout in base al dispositivo di destinazione).

P.S.3: Naturalmente l'aggiunta di DI sembra sproporzionata per il tuo piccolo pezzo di codice. Nel mondo reale, tuttavia, con classi di complessità del mondo reale, molto spesso lo sforzo DI aggiuntivo è proporzionalmente molto più lento

    
risposta data 05.03.2018 - 23:00
fonte
3

Applicare principi e "migliori pratiche" senza comprendere appieno il loro scopo può essere piuttosto distruttivo. Il D in solido è un famigerato.

L'inversione delle dipendenze legge a molti come "usa le interfacce". Il che non è poi così lontano, ma innesca molti a schiaffeggiare un'interfaccia su ogni classe che creano. Questo di solito non è di aiuto.

Ciò che significa in realtà è cercare di separare le dipendenze tra A e B introducendo una terza entità C. Quindi sia A sia B sanno C, ma non l'un l'altro.

Questo può essere utile, ma come altri già sottolineato, è necessario avere uno scopo per questo. Se non sai perché lo stai facendo, ti preghiamo di non farlo.

Le interfacce sono più preziose quando definiscono alcuni aspetti comportamentali di una classe. Questo è il loro valore principale. Usarli solo perché ti permette di testare il tuo codice è già un uso abusivo di un'interfaccia. Solitamente porta a interfacce che hanno una relazione uno a uno con le classi che rappresentano, il che viola l'I in SOLID, il principio di separazione delle interfacce.

Cat : IScratcher, IJumper, IPettable   // helpful

Cat : ICat    // utterly useless

Quindi, se esegui l'interfaccia ICat per il test, tieni presente che si tratta di un compromesso. In pratica stai dicendo "Non mi importa niente di SOLID, voglio solo testare la mia lezione".

Quello che dovresti veramente fare è avere metodi di test separati per IScratcher, IJumper e IPettable.

    
risposta data 06.03.2018 - 10:00
fonte
3

SOLID non è fine a se stesso, è un mezzo per un fine . Applicato al tuo esempio, questo significa rendere il codice SOLIDO quanto necessario, non di meno, non di più. Questo corrisponde anche al principio KISS.

  • ad esempio, se per scopi di test unitario è necessario disaccoppiare HelloService da Decorator , utilizzare DI. Se ritieni che test funzionali o di integrazione siano sufficienti, probabilmente non ne hai bisogno.

  • se vuoi riutilizzare HelloService , ma con decoratori e piè di pagina diversi, iniettarli come parametro è probabilmente la soluzione più "semplice e stupida" per mantenere il codice ASCIUTTO. Se c'è un solo decoratore e un piè di pagina, probabilmente non avrai nemmeno bisogno di classi separate per il decoratore e il piè di pagina

  • se è necessario evitare di introdurre una dipendenza diretta tra componenti, poiché fa parte di una lib generale, e la logica di Decorator e Footer deve essere fornita da un utente di tale lib ( OCP), quindi sarà richiesto DI

Soprattutto la D di SOLID è probabilmente la soluzione più semplice per questo tipo di problemi che vuoi risolvere, quindi è perfettamente in linea con KISS.

Se DI non è richiesto (ancora), quindi non iniziare a usarlo "just in case". Invece, applica YAGNI: refactor a DI non appena ne hai un reale requisito.

    
risposta data 05.03.2018 - 23:35
fonte
0

SOLIDO.

Il problema con KISS è la definizione di "semplice" dipende da chi chiedi. Dove il tuo codice di esempio presenta alcuni problemi concreti risolti con i "semplici" schemi di interfacce e non digitando mai la parola "static".

Il tuo codice sarà più lungo, ma non più complicato con le interfacce.

In effetti potresti scrivere un codice più breve ma probabilmente più complicato, forse una regexp? quale qualcuno abituato a regex direbbe "Ma è così semplice! perché hai bisogno di tutte quelle classi ??"

    
risposta data 05.03.2018 - 22:59
fonte

Leggi altre domande sui tag