Ridurre la complessità del codice sovrascritto

3

Ho appena iniziato a lavorare in un'azienda in cui ho ereditato un codice C # da uno sviluppatore precedente. Conosco bene la programmazione, ho una laurea in ingegneria + una (non terminata, lunga diversi anni) educazione al dottorato in informatica e > 10 anni di precedenti esperienze di programmazione "pratica", principalmente in C ++ e Java, ma anche in altre lingue.

Il mio problema è che il codice che ho ereditato è, a mio avviso, eccessivamente ingegnerizzato. Ho enormi problemi seguendo il flusso del programma e trovando qualsiasi implementazione concreta di qualsiasi cosa. La quantità di astrazioni è totalmente sbalorditiva e non c'è documentazione di sorta. Inoltre, è difficile eseguire il debug dell'applicazione poiché si tratta di un'applicazione server divisa in un server "GUI-client" e un "Control-Server" (anche un'astrazione relativamente inutile poiché funzionano sempre sulla stessa macchina e c'è un Rapporto 1: 1 tra di loro) che si interfaccia con l'hardware industriale che non è disponibile.

Per dare un esempio illustrativo, una delle classi ha un campo come questo:

IClientFactory<IClient<ICommunicationService>> communicationFactory;

Ho difficoltà a girarmi attorno visto che anche il programmatore precedente ha scritto questo codice (cioè non usando un bit shift, e questa è una delle poche cose documentate):

public static bool IsBitHigh(int value, int bitIndex) {
    int valueAbs = Math.Abs(value);
    if (bitIndex < 0)
        throw new ArgumentException("Bit index must be above or equal to 0");
    int result = valueAbs & Convert.ToInt32(Math.Pow(Convert.ToDouble(2.0), Convert.ToDouble(bitIndex - 1)));

        return (result > 0);
    }

Ci sono anche indicazioni che il programmatore precedente è rimasto sorpreso dal fatto che il lancio di float su "ints" le abbatte, e questo avviene dopo diversi anni nel settore.

Quindi dato questo ho due domande:

  • È questo il modo in cui il codice si presenta in genere nel settore? (Ho un background ingegneristico / di ricerca, quindi mi sono illuso che le persone stessero ancora usando i cicli for.)

E, ancora più importante:

  • C'è un modo semplice per ridurre la complessità del codice, cioè sostituire le interfacce con le loro implementazioni concrete? (Per invertire il senso del codice in un certo senso.)
posta user1794399 26.02.2015 - 16:56
fonte

1 risposta

5

My problem is that the code that I have inherited is, in my opinion, absurdly over-engineered. I have enormous problems following the program flow and finding any concrete implementations of anything. The amount of abstractions are totally mind-boggling and there is no documentation whatsoever.

Non è vero, trovo che molto C # e Java (e altri "linguaggi di sviluppo degli sviluppatori" che dispongono anche di strumenti per il refactoring e "twiddling" con il codice) hanno una preponderanza di questo tipo di base di codice, probabilmente perché facile da scrivere, c'è ancora molto tempo per armeggiare. Una società per cui lavoravo mi mostrò un'implementazione di riferimento di un webservice che aveva 1 metodo che richiedeva 1 parametro e restituiva una stringa ... ed era implementato usando 32 file di classe C # in 6 assiemi. E per finire ci fu un commento in uno di loro dicendo che avrebbe usato un'iniezione di dipendenza ma non voleva complicarlo troppo !!! (Un equivalente C sarebbe stato 32 linee di codice)

Quindi ... Penso che la cosa migliore da fare sia lavorare fino a quando non comprenderai i suoi livelli, poiché sono sicuro che lo sviluppatore precedente è riuscito a mantenere la struttura generale nella sua testa in modo che potesse lavorare con esso, con tempo potresti ottenere lo stesso modello mentale di dove sono tutti i bit per mantenerli.

Un'alternativa è capire le parti che si adattano e consolidarle per rimuovere gran parte dell'interfaccia. ad esempio, la GUI del client e il server di controllo possono essere uniti, ma ritengo che questo non sia il posto migliore per attaccare: potrebbe essere molto più lavoro aggiungere un controllo alla GUI (dato che devi eseguire in cascata le modifiche attraverso entrambi i componenti) ma questa è una pratica comune per lo sviluppo n-tier comunque.

Anche con la palude di interfacce, probabilmente sono OK nel complesso. Forse è necessario consolidarne alcuni - non necessariamente per le loro lezioni concrete in quanto ciò non ti darà molto, ma per rimuovere gran parte del plumbing astratto che le interfacce sono state messe in supporto. ICommunicationService suona come una buona interfaccia, un IClient<ICommunicationService> suona inutili fluff e liberarsi di quello potrebbe vedere IClientFactory andare anche come danno collaterale.

Tutto sommato, fai ciò che puoi. Ma sfortunatamente è piuttosto comune nel settore. Nessuno capisce più KISS: - (

    
risposta data 26.02.2015 - 17:20
fonte

Leggi altre domande sui tag