Esiste un principio di stile di codifica per rendere coerente l'uso della classe

0

Riesco a rivedere il codice che assomiglia spesso a questo:

class MyClass1 {

    constructor MyClass(initialiseParam1: Object) {
        // do something with initialiseParam1
    }

    initialiseStep2() {
        // do some more initialisation
    }
}

Per utilizzare MyClass1 devi fare due passaggi, prima per creare un oggetto e il secondo per chiamare il metodo initialiseStep2 .

Un'altra variante della stessa idea è la seguente:

class MyClass2 {        
    doSomethingPart1() {
        // part of some action
    }

    doSomethingPart2() {
        // complete the same action
    }
}

E per fare un uso singolo, devi chiamare due metodi separati.

Quello che non mi piace molto di entrambi è che un utente di questa classe ha bisogno di conoscenze interne su come usarlo e uno dei grandi obiettivi di design per cui combatto è quello di creare un'interfaccia pubblica in modo che è impossibile abusarne. Ad esempio, dovresti ottenere un errore di compilazione se fai qualcosa di stupido.

Ecco perché cerco di progettare in modo che qualsiasi cosa tu voglia fare sia una singola azione. Nessuna procedura di follow-up, nessuna configurazione di follow-up di un oggetto già costruito.

Spiegando questo ai miei colleghi vorrei fornire loro alcuni principi di progettazione con un nome e buoni esempi e spiegazioni su internet, ma fino ad ora non sono riuscito.

Qualcuno è a conoscenza di un simile principio?

    
posta eddyP23 16.10.2018 - 13:48
fonte

2 risposte

4

Il problema con gli oggetti che obbediscono a tale API è che hanno stato nascosto .

Un oggetto MyClass2 può già aver ricevuto un doSomethingPart1() tutto o meno. Non c'è modo di dire solo dal tenere l'oggetto e guardando il suo tipo. Allo stesso modo, un oggetto MyClass1 può essere già stato inizializzato tramite initializeStep2() o no. Ancora una volta, non esiste un modo chiaro per dire la differenza.

Questa è generalmente una brutta cosa. Chiedere a un oggetto di fare un servizio dovrebbe richiedere un'interazione una , non diverse interazioni che devono essere nell'ordine corretto. Il fatto stesso che sia possibile eseguire operazioni fuori servizio introduce la possibilità di errori di utilizzo laddove non ce ne dovrebbe essere uno.

Di norma, dovresti dividere le operazioni in due se una fase richiede enormi quantità di risorse che devono essere ammortizzate in più operazioni successive dello stesso tipo. Ad esempio, è un enorme sforzo per ordinare una lista, ma in seguito ogni ricerca nell'elenco diventa molto più semplice.

Anche allora, sebbene sia una buona idea incapsulare un tale flusso di lavoro in oggetti, non dovrebbe venire sotto forma di due metodi sort() e lookup() con l'avvertimento "Non puoi cercare fino a quando non sei tu" ho risolto! ". Una soluzione migliore sarebbe avere l'ordinamento nel costruttore e includere solo lookup() nell'API.

    
risposta data 16.10.2018 - 14:00
fonte
1

Hai ragione sul fatto che questo design attuale è sbagliato e il tuo obiettivo di avere una chiamata da completare in azione è la convenzione appropriata da seguire. Ci sono molti modi diversi per mostrare quanto questo sia cattivo in quanto viola le idee sovrapposte di molti principi diversi. Alcuni o tutti questi possono essere utili esempi per spiegare perché questo è cattivo.

  • Esiste il principio della responsabilità unica, perché il costruttore sta facendo meno di una cosa quando dovrebbe fare esattamente una cosa.

  • Allo stesso modo c'è una ripetizione che dovrebbe essere evitata se devi sempre dichiarare new class() e class.initialize() , quindi dovrebbero essere gestiti da un singolo metodo.

  • C'è anche il principio del minimo stupore / sorpresa, una volta che ho un nuovo oggetto l'aspettativa è che dovrei essere in grado di chiamare qualsiasi metodo pubblico, ma queste classi mi sorprendono rompendo se initialze2() non è chiamato prima.

  • Gli oggetti non riescono a gestire il proprio stato dall'interno dell'oggetto, non incapsulano il loro stato.

  • Anche lo spirito di dire non chiedere viene violato, non hai metodi / proprietà che ti chiederebbero di stato, ma hai un reale bisogno per loro nel disegno attuale. Il modo corretto per seguire questo principio è fare in modo che gli oggetti facciano ciò che gli dici quando glielo dici, non rimuovono alcun modo per scoprire lo stato interno ma richiedono conoscenza per utilizzare correttamente gli oggetti.

risposta data 16.10.2018 - 15:01
fonte

Leggi altre domande sui tag