Spesso utilizza le costanti int come parametri nella comunicazione tra oggetti considerati design errato?

0

Un'app a cui sto lavorando è progettata con MVC. I componenti spesso interagiscono tra loro passando costanti int, che poi devono essere interpretate con dichiarazioni if . Mi chiedo se questo sia considerato un cattivo design OO. (Non specificamente con MVC, ma in generale).

Ad esempio:

Quando l'utente fa clic su un pulsante specifico, al controller viene indicata la vista controller.somethingHappened(Controller.SOME_INT_VALUE);

La vista usa un valore int costante nel controller come un messaggio per dire cosa è successo. Il controller deve quindi avere un sacco di istruzioni if per interpretare il messaggio dalla vista. Per esempio:.

public void somethingHappened(int message){
    if(message == AN_INT_VALUE) doSomething();
    if(message == ANOTHER_INT_VALUE) doSomeThingElse();
    if(message == A_DIFFERENT_INT_VALUE) doAnotherThing();
}

Di conseguenza il controller passa un altro valore int nel modello, come un messaggio per fare qualcosa. Cioè model.doSomething(Model.SOME_INT_VALUE); .

Quali forze per modellare hanno anche un sacco di dichiarazioni if :

public void doSomething(int message){
    if(message == AN_INT_VALUE) doSomething();
    if(message == ANOTHER_INT_VALUE) doSomeThingElse();
    if(message == A_DIFFERENT_INT_VALUE) doAnotherThing();
}

In questo modo sia il controller che il modello hanno un sacco di if s per interpretare i messaggi ricevuti.

Questo è considerato brutto e / o cattivo design? Dovrei provare a passare oggetti reali in metodi, o effettuare chiamate di metodo più specifiche - invece di passare costanti che devono essere interpretate con un gruppo di if s? O questa pratica consiste nell'usare molte costanti come messaggi considerati ragionevoli?

Se è considerato un cattivo design, come posso evitare questo?

(Nota: ai fini di questa domanda mi riferisco anche alle enumerazioni) .

    
posta Aviv Cohn 06.05.2014 - 18:56
fonte

2 risposte

1

Is this considered ugly and/or bad design?

Sì.

Should I [...] make more specific method calls - instead of passing constants that have to be interpreted with a bunch of ifs?

Sì, è esattamente quello che dovresti fare. A meno che non ci sia un motivo per non farlo. Dato che hai già pensato a te stesso questa opzione molto più pulita, ho il sospetto che potrebbe esserci, ma non è discernibile dalla tua domanda.

Aggiornamento: se i metodi chiamati hanno funzionalità duplicate, la soluzione orientata agli oggetti è mettere la funzionalità che differisce in classi separate che implementano tutte la stessa interfaccia, e chiamalo dall'interno della funzione, usando il polimorfismo invece del branching esplicito.

Quindi, utilizzando le informazioni del commento, chiameresti

controller.applyStyle(new BoldStyle());

o

controller.applyStyle(new UnderlineStyle());

dove BoldStyle e UnderlineStyle sono entrambe classi che implementano un'interfaccia Style (o ereditate dalla stessa superclasse) che contiene uno o più metodi che fanno le cose diverse e che sono chiamato dal metodo applyStyle() .

    
risposta data 06.05.2014 - 21:50
fonte
1

Ci sono diverse scelte qui, in ordine crescente di preferenza (l'ultima più preferibile):

  • Bit (flag) in un numero intero. Può essere fonte di confusione, ma consente di comprimerli molti in un singolo int. Quindi

    DO_THIS = 1 DO_THAT = 2 DO_ANOTHER = 4 DO_ZING = 5

    esegui (DO_THIS | DO_THAT)

    if (command & DO_THIS {doThis ();} ... etc

  • Comandi integer

    DO_THIS = 1 DO_THAT = 2 DO_ANOTHER = 3

    esegui (DO_THIS, DO_THAT)

    for (comando nei comandi):     if (comando == DO_THIS) {doThis (); }

  • Preferisco le stringhe sugli int, solo perché sono più leggibili

    DO_THIS="questo" DO_THAT="quello" ...

  • Costanti "Typesafe" (nel caso in cui non ci siano enumerazioni in giro)

    DO_THIS = new Object (); DO_THAT = new Object ();

    eseguire (DO_THIS, DO_THAT);

    for (comando nei comandi)    if (comando == DO_THIS) {doThis (); }

  • Enum è una formalizzazione di "costanti Typesafe", quindi usalo se ce l'hai

...

Generalmente, tuttavia, questi schemi sono utili quando le chiamate devono essere serializzate e amp; trasmesso tra processi. Se stai solo effettuando chiamate da una sezione di codice a un'altra, puoi semplicemente identificare cosa vuoi fare con i nomi delle funzioni. Scrivendo una sorta di funzione "router" che effettua una chiamata alla funzione di livello inferiore, replica ciò che il linguaggio fa per te, quindi potresti pensare più a lungo se ne hai bisogno.

...

Cioè, cerco di tenerlo così che il 90% del mio codice sembra uscito direttamente da "Impara Java in 30 giorni" (o Python, o qualsiasi altra cosa). Cioè, il codice dovrebbe semplicemente usare la lingua in un modo davvero semplice quasi sempre. Ci dovrebbe essere una buona ragione per cui non puoi semplicemente farlo nel modo più semplice prima di passare a una generalizzazione più ampia.

    
risposta data 06.05.2014 - 19:46
fonte

Leggi altre domande sui tag