Metodo per tutti gli oggetti per il controllo delle condizioni che include anche il concatenamento del metodo e l'evitamento delle variabili

2

(Attualmente sto usando groovy ma dovrebbe applicarsi alla maggior parte dei linguaggi OO quindi inserisco anche il tag langauge-agnostic)

Cerco di programmare in uno stile di funzione che include anche il concatenamento del metodo e l'evitamento delle variabili. Perciò spesso mi trovo a scrivere codice con il metodo with in groovy che ogni oggetto ha. Funziona così:

someobject
.doSomething()
.doEvenMore() //this results in an object that I need check for some condition, e.g. a String
.with { String result ->
    if (result != "I AM A CORRECT RESULT")
        throw new Exception("assertion failed")
    else
        return result  //need to do this because else the closure will return null
}
.doAnotherThingOnTheResult()
//and so on

(Vedi anche link per un vero esempio di vita che ho chiesto qualche tempo fa)

Questo è piuttosto inconciliabile, quindi stavo cercando un modo migliore per verificare le condizioni senza utilizzare with . Mi è venuta un'idea che mi piacerebbe sentire le tue opinioni. Cioè, un metodo che tutti gli oggetti hanno e che possono essere usati in questo modo:

someobject
.doSomething()
.doEvenMore() //this results in an object that I need check for some condition, e.g. a String
.assertTrue (new Exception("custom exception")) { it == "I AM A CORRECT RESULT" }
.doAnotherThingOnTheResult()
//and so on

o per comportamento predefinito con un tipo di eccezione predefinito

someobject
.doSomething()
.doEvenMore() //this results in an object that I need check for some condition, e.g. a String
.assertTrue { it == "I AM A CORRECT RESULT" } //results in AssertionException or sth similiar
.doAnotherThingOnTheResult()
//and so on

In groovy posso far sì che ogni (nuovo) oggetto creato sia decorato con un tale metodo. Che cosa ne pensate a riguardo? Ci sono modi migliori o dovrei rimanere con il metodo with ?

    
posta valenterry 24.11.2014 - 16:12
fonte

2 risposte

1

In primo luogo, penso che sia una buona idea rifattorizzare la parte with nella sua funzione. Rende il codice IMHO più facile da leggere e corrisponde al "Single Level of Abstraction" principio, che è una caratteristica del codice pulito.

In secondo luogo, se è una buona idea decorare la classe ogni del tuo programma con questo metodo aggiuntivo, dipende. Lo farei solo se hai bisogno di questa funzione su tutto il tuo programma, in molte classi. Altrimenti, lo limiterei alle classi che usano veramente il metodo. Ciò aiuta ad evitare conflitti di denominazione non intenzionali.

    
risposta data 24.11.2014 - 17:08
fonte
3

Sono fuori di testa se il tuo codice dovrebbe essere chiamato un'interfaccia fluente o un naufragio del treno . In entrambi i casi, il concatenamento dei metodi non dovrebbe essere sovrautilizzato perché riduce la leggibilità. Ho esperienza di prima mano da un progetto in cui mi sono ritrovato a scrivere funzioni wrapper per accorciare alcune catene. Inoltre, alcune persone come Robert C. Martin in "Clean Code" Capitolo 3 suggeriscono che si dovrebbe sforzarsi di separare i comandi dalle query, che il codice chiaramente non fa. Non dico che questa sia una verità assoluta, ma dovresti stare più attento con il metodo di concatenamento. Dopotutto, lo stile funzionale non dice che si debba concatenare tutto ma piuttosto che si dovrebbe sforzarsi di costruire codice da funzioni che non usano lo stato implicito. Quindi, ovviamente, dovresti seguire il suggerimento e il coefficiente with di Doc Brown in una funzione separata, ma devi anche controllare se stai sfruttando troppo il metodo di concatenamento .

Ad esempio, potrebbe essere meglio assegnare il risultato del calcolo prima di verificare invarianmente una variabile, quindi verificare che la variabile soddisfi il controllo e quindi continuare con il calcolo. Potresti persino decidere di racchiudere diverse sottochiavi comunemente utilizzate in funzioni separate con un nome descrittivo.

Se fosse Haskell, avresti potuto restituire Maybe.Some(yourobj) da ciascun metodo e fare affidamento sul compilatore per interrompere il calcolo non appena viene restituito Maybe.None . In questo modo, un metodo di verifica restituirà yourobj invariato se è OK e restituirà None in caso contrario. In Java c'è una cosa molto simile chiamata Optional e questo articolo spiega come può essere usato per risolvere il tuo problema in un modo diverso.

    
risposta data 24.11.2014 - 19:53
fonte