Evitare pacchetti con un accoppiamento efferente elevato

2

Uso il linguaggio java per sviluppare applicazioni Android, dopo l'analisi statica, lo strumento avverte dell'accoppiamento efferente alto.

Qual è la ragione di questo avvertimento? Si tratta di AComModel che viene esteso da un'altra classe?

Ci sono 4 classi sotto le quali lo strumento ci avverte su di loro. Spero di aver fatto una domanda logica, ma davvero non capisco quale sia il problema?

public class AComModel {    
    public String GetComBusinessKey() {
        return "none";
    }
}


@JsonIgnoreProperties(ignoreUnknown = true)
public class StepOneCom extends AComModel {

    public View vi;
    public ArrayList<SummaryViewModel> lstSmr;

    @Override
    public String GetComBusinessKey() {
        return "shvi";
    }

}


@JsonIgnoreProperties(ignoreUnknown = true)
public class StepTwoCom extends AComModel {

    public ArrayList<AccViewModel> lstAcc;
    public SummaryViewModel c1;


    @Override
    public String GetComBusinessKey() {
        return "shvi";
    }

}


@JsonIgnoreProperties(ignoreUnknown = true)
public class StepThreeStepTwoCom extends AComModel {

    public StepFourCom stepFourCom;

    @Override
    public String GetComBusinessKey() {
        return "cashadvi";
    }
}
    
posta talhakosen 18.02.2014 - 14:59
fonte

1 risposta

3

Senza vedere il codice completo nel tuo progetto, è impossibile dire con certezza al 100%, ma dato che lo strumento stava eseguendo l'analisi del codice statico , questo avviso indica uno dei seguenti:

  • StepOneCom non utilizza metodi e campi specifici di nessuna delle classi View , ArrayList , SummaryViewModel
  • StepTwoCom non utilizza metodi e campi specifici di nessuna delle classi AccViewModel , ArrayList , SummaryViewModel
  • StepThreeCom non utilizza metodi e campi specifici della classe StepFourCom

o qualche sottoinsieme di ciò che è elencato sopra, o anche di tutto quanto sopra insieme.

Probabilmente il modo più semplice per verificare esattamente che cosa si lamenti sarebbe sostituire (dove non interrompe la compilazione) le classi specializzate menzionate sopra con il più generale Object e controllare se gli avvertimenti scompaiono.

Questo è basato sulla spiegazione di accoppiamento efferente dato in Wikipedia:

a metric in software development. It measures the number of data types a class knows about.

This includes inheritance, interface implementation, parameter types, variable types, and exceptions.

A large efferent coupling can indicate that a class is unfocused. It may also indicate brittleness, since it depends on the stability of all the types to which it is coupled.

In termini più semplici, se si è in grado di sostituire un tipo specializzato con uno standard, come Object , senza interrompere la compilazione, ciò significa che non è necessario che la classe sia consapevole di quel tipo specializzato e che introducendo questa "conoscenza inutile" rendi il codice più difficile da mantenere.

Il lettore del tuo codice dovrebbe rompere la mente cercando di indovinare perché hai coinvolto View , ArrayList , SummaryViewModel , AccViewModel , StepFourCom dove il compilatore a quanto pare dice loro che lo standard standard Object farebbe altrettanto bene.

Mentre ci siamo, vorrei anche sottolineare che il modo in cui sono presentati nello snippet, il codice sembra provocare una violazione ancora più grave dei principi suggeriti in tutorial sulla lingua base :

  • Use the most restrictive access level that makes sense for a particular member. Use private unless you have a good reason not to.
  • Avoid public fields except for constants... Public fields tend to link you to a particular implementation and limit your flexibility in changing your code.

A meno che tu non sia sicuro al 200% che hai bisogno che i campi siano pubblici e puoi fornire una giustificazione a prova di proiettile per questo, pensa ai modificatori di accesso pubblico in codice come una fonte dei peggiori mal di testa e incubi futuri:

public View vi;
public ArrayList<SummaryViewModel> lstSmr;

Le indicazioni fornite nel tutorial sono lì per un motivo, si basano su una dolorosa esperienza di più programmatori che hanno provato in questo modo e hanno scoperto che è un vicolo cieco.

Una parte meno sfacciata, ma ancora piuttosto sdrucciolevole del design nel tuo frammento di codice è un uso ingiustificato dell'ereditarietà. L'ereditarietà comporta alcuni obblighi e rischi aggiuntivi per le classi che lo utilizzano, e ti conviene assicurarti che sia esattamente ciò di cui hai bisogno.

Ne parlo perché il modo in cui il codice è scritto nello snippet di codice, può essere altrettanto bene se AComModel è un'interfaccia invece di una classe e solo dichiarare GetComBusinessKey invece di fornire l'implementazione predefinita, in modo che StepOneCom , StepTwoCom , StepThreeCom implementerebbe tale interfaccia invece di estendere una classe.

    
risposta data 18.02.2014 - 16:03
fonte

Leggi altre domande sui tag