Sugar Classes come codice odore

3

Nel corso degli anni ho spostato avanti e indietro l'idea di creare Sugar Classes .

Prima o poi mi ritrovo a ripetere la stessa operazione su un tipo esistente. Come la manipolazione delle stringhe, i calcoli della data-ora ... in questi casi sono tentato di avvolgere l'oggetto in una classe personalizzata e ottenere uno zucchero sintattico extra come:

Time.now().addDays(3).addMinutes(30).diffFrom( otherTime ).toHuman()

La maggior parte delle lingue che conosco hanno la propria libreria I will sugarcoat this data type for you . Tuttavia, data l'attuale tendenza dello stile funzionale, mi sto chiedendo se le classi di zucchero siano così salutari.

Questo modello ha un nome ufficiale di odore di codice?

Voglio approfondire la ricerca su questo argomento, ma sto riscontrando un problema per denominare correttamente il modello.

    
posta SystematicFrank 25.06.2017 - 08:37
fonte

4 risposte

7

Ho un'intera libreria per un sacco di questa roba, specialmente sulle operazioni con le stringhe. Spesso questi metodi sono solo 3-liners, ma ora sono solo in un posto.

Non vedo una cosa negativa, perché il codice viene riutilizzato pesantemente, molti controlli sono nella maggior parte dei metodi che probabilmente non mi preoccuperei di scrivere, se lo avessi scritto da qualche parte nel codice dell'applicazione. Questi metodi di supporto hanno avuto molti test unitari nel corso degli anni e se ho scoperto un nuovo caso limite, lo aggiungo in un unico posto e non in tutto il codice dell'applicazione.

TL, DR: Lavorare in questo modo porta a un codice più robusto e meglio testato, che è facile da mantenere.

    
risposta data 25.06.2017 - 09:00
fonte
4

Il problema con tali classi e metodi non è evidente nel singolo caso.

Noterai comunque il codice, quando avrai creato una grande libreria e lo stai importando in tutte le basi del codice solo per utilizzare una o due delle funzioni.

Fondamentalmente si tratta di una domanda di responsabilità, ed è probabile che tutte le funzionalità di base di cui il tipo dovrebbe essere ragionevolmente responsabile siano già state incorporate in quel tipo.

Dovrebbe essere una barra piuttosto alta per giustificare che ToHuman() , ad esempio, appartiene al tipo piuttosto che al particolare modello, vista o progetto che richiede la logica.

    
risposta data 08.07.2017 - 10:12
fonte
1

Come dice Simon, manteniamo una libreria (in realtà un numero) per questo tipo di cose. È fantastico.

In .NET, ad esempio, abbiamo una libreria di base che include manipolazioni di stringhe, eccezioni generiche che sembrano essere sempre mancanti ( BadFormatException , altre). Questo codice è altamente testato e acquisisce una notevole quantità di robustezza con il passare degli anni. (Fa anche un bel template per altre piattaforme / linguaggi, perché anche se potrebbe non essere la stessa sintassi di programmazione, non perdi veramente oh, ricordati di controllare questo ).

Siamo arrivati al punto di includere progetti separati all'interno del nostro "framework". Esempi:

Dymeng  // core, common
Dymeng.Data
Dymeng.Net
Dymeng.Web
Dymeng.Web.Mvc
Dymeng.Console  // has our args management, etc

Questi sono tutti codici comuni che richiediamo da tutti i progetti. Se sono in un livello MVC, aggiungo Dymeng.Web.Mvc e ho una libreria di solidi aiutanti per semplificare le cose. In effetti, non sono sicuro di come potremmo vivere senza di esso. Suddividendo tutti questi piccoli timer in progetti separati, produciamo le dll e cariciamo solo quelle necessarie nei progetti di lavoro.

Abbiamo un sistema per stabilire se anche questi vanno in metodi statici o di estensione. Per questi metodi di supporto (al contrario delle classi di helper), li scriviamo come metodi statici. I metodi di estensione chiamano semplicemente il metodo statico "principale" (simile al modo in cui non scriveremo codice logico in un metodo del gestore di eventi, ma utilizzeremo invece il gestore di eventi per chiamare il metodo "logico").

Spesso scriverò un metodo statico, poi un po 'più tardi lavorerò su qualcosa e penso so che ho scritto questo, dov'è quell'estensione myString.PadLeft() ? - a quale punto è un salto rapido nella lib per aggiungere il metodo di estensione per il metodo statico che esisteva già.

In realtà, a mio avviso, la cosa migliore di tutto ciò è il fatto che una volta che si ottiene un sistema di utilizzo di una libreria / serie di librerie comuni come questa, il codice all'interno delle librerie diventa molto ben utilizzato e altamente affidabile . Sai che se scrivi un altro GetLineFromFile(path, lineNumber) (o qualsiasi altra cosa) potresti perdere qualcosa anche se l'hai scritto quattro volte negli ultimi tre anni: con una biblioteca, sai che funziona e non devi preoccupartene .

    
risposta data 08.07.2017 - 15:11
fonte
0

Hai indicato tre diversi livelli di attività:

Crea il valore per il confronto:

Time.now().addDays(3).addMinutes(30)

Confronto:

.diffFrom( otherTime )

Trasforma in una versione leggibile dall'uomo (forse una stringa ??)

.toHuman()

Non ci sono problemi con un'interfaccia fluente (si chiama così). Tuttavia, l'utilizzo di un'interfaccia fluente non renderà obsoleta la responsabilità di identificare e separare attività isolate.

L'unico problema che vedo è l'ultima operazione ".toHuman ()". Questa sembra essere un'operazione che non dovrebbe essere parte di questa catena di chiamate. Mi aspetterei qualcosa di simile:

.to(new HumanReadable())

dove HumanReadable estende Printable.

Quindi la responsabilità su cosa produrre come risultato è incapsulata e non legata all'API.

    
risposta data 25.06.2017 - 09:27
fonte

Leggi altre domande sui tag