La rilevabilità degli sviluppatori è un problema quando si usano i principi SOLID?

10

Faccio una linea di app aziendali in cui tutti gli altri sviluppatori sono abituati a fare applicazioni CRUD di base o sono focalizzati esclusivamente sulla creazione di interfacce graziose / funzionali e sto ottenendo molto da quanto segue.

"Con il modo in cui usiamo per farlo il dipendente avrebbe tutte le cose che potresti fare con un dipendente." Ed era vero. Quella "Classe" conteneva migliaia di righe di codice e qualsiasi cosa si potesse fare con un dipendente era lì. O, peggio ancora, c'era una tabella dei dati dei dipendenti e ogni sviluppatore ha capito come fare ciò che volevano fare nel gestore di eventi.

Tutte le cose cattive su questo approccio era vero, ma almeno lo sviluppatore utilizzando dipendente potrebbero, senza andare ad altri documenti, capire come iscriversi al dipendente in un piano di salute, danno un aumento di paga, il fuoco, il noleggio, il trasferimento ecc Lo stesso vale per il manager e tutte le altre idee importanti. Oppure, se hanno utilizzato l'impiegato altre tabelle di dati necessarie, potrebbero semplicemente fare ciò che volevano.

Sì, c'era molto codice duplicato. Sì, era un codice molto fragile. Sì, testarlo era molto più difficile del necessario. Sì, la modifica della funzionalità è stata la paura di indurre e Copy Paste è stato naturale a causa dell'approccio.

Ma potevano almeno scoprire ciò che era disponibile con la creazione di una classe o che potevano fare quello che devono ottenere fatto senza dover capire la differenza tra le interfacce, classi astratte, classi concrete ecc E non hanno bisogno di cercare qualsiasi cosa diversa dai metodi restituiti da intellisense o conoscere le tabelle in cui i dati risiedevano.

Ho cercato su Google / abbaiato e persino yahoo! d ma non ho trovato alcun riconoscimento di questo problema.

Quindi forse non c'è un problema e mi manca solo qualcosa. Ho tormentato il mio cervello cercando di capire una soluzione in cui lo sviluppatore (s) che non funzionano il reale comportamento / progettazione facilmente può scoprire come fare qualcosa, senza dover fare riferimento a documenti esterni o la scansione dei nomi di classe nelle varie componenti / progetti per trovare quello che sembra funzionerà.

L'unica cosa che sono riuscito a venire in mente è avere questi, in mancanza di un nome migliore, "Tabella di classe di contenuto" che non fa altro che restituire le classi attuali (e in realtà la maggior parte di loro sono interfacce ma non conosciamo la differenza o anche la cura) che altri sviluppatori possono utilizzare per eseguire i compiti effettivi desiderati. Ancora finiscono con classi molto grandi ma non c'è quasi nessun comportamento in loro.

Esiste un modo migliore per non richiedere una conoscenza approfondita del livello intermedio in cui avviene l'effettiva implementazione di SOLID?

Fondamentalmente quello che sto chiedendo è un modo per consentire agli sviluppatori di tipo CRUD di continuare a essere sviluppatori CRUD in un sistema molto complesso

    
posta ElGringoGrande 09.10.2011 - 21:51
fonte

3 risposte

4

Sembra che quello che hai descritto (cioè la classe Employee che ha TUTTO il codice possibile che potresti fare con un dipendente) è un modello estremamente comune che ho visto molto spesso. Alcuni di quel codice che ho scritto prima sapevo che sarebbe stato meglio.

Ciò che inizia come una classe che dovrebbe rappresentare una singola entità con un insieme gestibile di metodi, si trasforma in qualcosa che è un incubo da mantenere perché ogni funzione e ogni versione continuano ad aggiungere sempre più alla stessa classe. Questo va contro i principi SOLID che dicono che dovresti scrivere una classe una volta e resistere alla tentazione di modificarla più e più volte.

Qualche tempo fa (prima di scoprire modelli di progettazione o SOLID come promossi da altri), ho deciso che il mio prossimo progetto avrebbe cambiato le cose un po '. Stavo lavorando su un server che fungeva da interfaccia tra due piattaforme molto grandi. Inizialmente, era necessaria solo la sincronizzazione della configurazione, ma potevo vedere che questo sarebbe stato un posto logico per molte altre funzionalità.

Quindi, invece di scrivere una classe che esponeva metodi, ho scritto classi che rappresentavano metodi (si è rivelato essere il pattern "Comando" di GoF). Invece di fare il lavoro per il cliente, tutte le mie principali classi di applicazione divennero titolari di stati persistenti e divennero molto più brevi. Ogni volta che dovevo aggiungere un nuovo metodo di interfaccia al servizio stesso, creavo semplicemente una nuova classe con il metodo Execute () che avviava tutto. Se più comandi avevano qualcosa in comune, derivavano dalla classe base comune. Alla fine la cosa aveva 70+ diverse classi di comando e l'intero progetto era ancora molto gestibile ed è stato davvero un piacere lavorarci.

La tua "classe TOC" non è troppo lontana da quello che ho fatto. Avevo una fabbrica astratta (GoF) che era responsabile per i comandi di istanziazione. All'interno della classe factory, ho nascosto la maggior parte dei dettagli dietro la classe base e le macro in stile ATL, quindi quando un programmatore ha dovuto aggiungere o cercare una richiesta, sono entrati e hanno visto solo:

BEGIN_COMMAND_MAP()
    COMMAND_ENTRY( CChangeDeviceState )
    COMMAND_ENTRY( CSetConfiguration )
    ....
END_COMMAND_MAP()

In alternativa (o in aggiunta a), puoi mettere tutte le tue effettive classi di comando in uno spazio dei nomi separato in modo che quando le persone stanno codificando e abbiano bisogno di eseguire qualcosa, scrivono solo il nome dello spazio dei nomi e Intellisense elenca tutti i comandi che hai definito . Quindi ogni comando include tutti i metodi get / set che determinano esattamente quali sono i parametri di input e output.

Puoi anche esplorare l'uso del modello di facciata (GoF). Invece di esporre più di 1000 classi ai tuoi ingegneri CRUD. Nascondili tutti dietro una singola classe che espone solo ciò che è necessario. Continuerò ad avere ogni "azione" come classe, ma la tua classe Facade può avere metodi che istanziano ciascuna delle tue azioni e di nuovo, con Intellisense vedrebbero immediatamente ciò che è disponibile. Oppure Facciate hanno metodi reali, ma internamente li fanno istanziare i comandi, metterli in coda e attendere le risposte. Quindi torna come se fosse stata effettuata una normale chiamata di metodo.

(*) Non volevo entrare in troppi dettagli, ma in realtà avevo set di classi "Command" e "CommandHandler". Questo separava la responsabilità di gestire / accodare / serializzare i parametri in / out da classi che effettivamente "gestivano" quei comandi.

    
risposta data 10.10.2011 - 05:45
fonte
0

Può essere un problema. Soprattutto se si nominano le cose male. Ma ci sono un certo numero di soluzioni senza ricorrere a classi complesse. Diamine, una classe con troppi metodi può essere ugualmente difficile da navigare con Intellisense.

Prova ad usare gli spazi dei nomi (C #) o i pacchetti (Java), o qualunque concetto simile abbia il tuo linguaggio (mi riferirò a tutti come spazi dei nomi), per semplificare il problema.

Inizia con il nome della tua azienda. Ciò limita l'Intellisense solo ai namespace scritti da voi stessi. Quindi, se hai più applicazioni, usa la seconda parte dello spazio dei nomi per dividerle. Includere uno spazio dei nomi Core, per cose che esistono tra le applicazioni. Quindi suddividiamo le cose in tipi di funzionalità. E così via.

Se lo fai bene, ti ritroverai con oggetti molto facilmente individuabili.

Per fare il tuo esempio, se voglio la convalida dell'Utente, scrivo "MyCo". e mi dà una lista di spazi dei nomi delle applicazioni. So che il database degli utenti è utilizzato in tutte le nostre app, quindi scrivo "Core". quindi ottengo un elenco di tipi di funzionalità. Uno di questi è "Validazione", quindi sembra una scelta ovvia. E lì, all'interno di Validation, è "UserValidator" con tutte le sue funzionalità.

Come succede, per le cose che uso molto, ricorderò rapidamente i nomi, o almeno le convenzioni. Poiché apporto molte modifiche alle regole di convalida, saprò che tutte le mie classi di convalida sono chiamate FooValidator, dove Foo è il nome della tabella. Quindi in realtà non avrò bisogno di attraversare i namespace. Digiterò UserValidator e lascerò che l'IDE faccia il resto del lavoro.

Ma per cose che non riesco a ricordare, è ancora piuttosto facile trovarle. E quando lo faccio, posso rimuovere il prefisso dello spazio dei nomi.

    
risposta data 10.10.2011 - 00:51
fonte
0

Dal momento che li definisci come sviluppatori fondamentalmente "CRUD", supponiamo che tu non pensi che siano molto bravi. Non sappiamo se questo significa che anche loro non capiscono il tuo dominio aziendale. Se capiscono il dominio, le classi dovrebbero avere senso per loro. Sapendo che diverse classi sono state costruite, dovrebbero prima dare un'occhiata, chiedere in secondo luogo, considerare la possibilità di costruire da zero come terza opzione.

Per quanto sappia sapere come usare / riutilizzare automaticamente una classe solo osservandola non ci si dovrebbe aspettare la prima volta. Avrai bisogno di documentare e possibilmente fornire ulteriori spiegazioni attraverso l'addestramento o eventualmente durante la revisione del codice.

Molte API e progetti open source forniscono documentazione, esempi di codice e altre spiegazioni. Potrebbe non essere necessario che l'utente sia amichevole, ma non c'è modo di aggirarlo. Insegnagli bene.

    
risposta data 10.10.2011 - 02:30
fonte

Leggi altre domande sui tag