È sbagliato utilizzare qualsiasi tipo di parametro per determinare il comportamento?

5

Secondo È sbagliato per usare un parametro booleano per determinare il comportamento? , non dovrei usare un parametro booleano per cambiare il comportamento all'interno di una funzione. Che ne dici di altri tipi di parametri?

Ad esempio, se provo a utilizzare una stringa anziché booleana:

void f(str){
    if(str==='a'){
        a();
    }else if(str==='b'){
        b();
    }else{
        c();
    }
}

soffre anche dei problemi come i parametri booleani? È vero che dovremmo dividere i metodi con diversi comportamenti in più metodi con un solo comportamento, indipendentemente dal tipo di parametro (ad esempio: booleano, stringa, enum ...)?

    
posta mmmaaa 27.02.2018 - 03:33
fonte

2 risposte

6

Mi piace il polimorfismo. Lo consiglio a tutti i miei amici. Una soluzione polimorfica sarebbe simile a questa:

f(thingy) {
    thingy.doIt()
}

class A { doIt() { a(); } }

class B { doIt() { b(); } }

class C { doIt() { c(); } }

thingyFactory(str){
    if(str==='a'){
        return A();
    }else if(str==='b'){
        return B();
    }else{
        return C();
    }
}

f(thingyFactory("a"))
f(thingyFactory("b"))
f(thingyFactory("c"))

Aspetta, sembra che tu stia usando javascript. Ecco un po 'di polimorfismo funzionale.

a = function (){ document.writeln( "<br> a" ); }
b = function (){ document.writeln( "<br> b" ); }
c = function (){ document.writeln( "<br> c" ); }


factory = function(str) {
   if(str==='a'){
        return a;
    }else if(str==='b'){
        return b;
    }else{
        return c;
    }
}

polymorphic = factory('b');
polymorphic();

Come puoi vedere finiamo per usare comunque un parametro. Non si tratta tanto di non usare mai i parametri per prendere decisioni. Si tratta di non accoppiare queste decisioni con il fare ciò che è stato deciso. A volte prendere queste decisioni è costoso, a volte possiamo renderle in fase di compilazione. a volte è solo difficile da guardare, a volte vuoi diverse aree di codice per gestire queste due responsabilità separate.

E, naturalmente, a volte i puristi OO sono ingegneri. Non fare mai cose del genere senza capire perché stai facendo cose del genere. Fare questo ti fa qualcosa. Assicurati di beneficiare di quel qualcosa. Altrimenti tutto quello che ottieni è più codice.

    
risposta data 27.02.2018 - 06:16
fonte
0

Mi piace la risposta di @ CandiedOrange, ma per completezza, ci sono altri modi in cui puoi realizzare anche questo. È possibile utilizzare una mappa (talvolta denominata hash o dizionario) per mappare gli input alle funzioni da chiamare. Non si specifica una lingua, ma in C ++, sarebbe simile a questa:

#include <iostream>
#include <map>

typedef void (*actionFunction)();

void functionA()
{
    std::cout << "a\n";
}

void functionB()
{
    std::cout << "b\n";
}

int main(int argc, char *argv[])
{
    std::map<char, actionFunction>  functionMap; // <- this is the map of characters to functions
    functionMap [ 'a' ] = functionA;
    functionMap [ 'b' ] = functionB;

    functionMap [ 'a' ](); // <- Calls the function associated with 'a'

    return 0;
}

Puoi fare una cosa simile nella scala C con una serie di record che contengono la mappatura sopra:

#include <stdio.h>

typedef void (*actionFunction)();

typedef struct functionMap {
    char            index;
    actionFunction  func;
} functionMap;

void functionA()
{
    printf("a\n");
}

void functionB()
{
    printf("b\n");
}

int main()
{
    functionMap fMap[] = {  // <- here's the map
        { 'a', functionA },
        { 'b', functionB }
    };
    size_t  numMaps = sizeof(fMap) / sizeof(fMap [ 0 ]);
    char someInput = 'a';

    for (size_t i = 0; i < numMaps; ++i)
    {
        if (fMap [ i ].index == someInput)
        {
            fMap [ i ].func(); // <- this calls the function associated with "someInput"
            break;
        }
    }

    return 0;
}

Questi rientrano nella categoria più ampia di programmazione basata su tabella o basata sui dati .

    
risposta data 27.02.2018 - 07:01
fonte

Leggi altre domande sui tag