Come evitare codice ridondante nella progettazione dell'ereditarietà in C ++

1

Dire che ho una classe Base chiamata Car e ha 3 classi derivate dire Ford , Honda e Audi .

Il problema è che tutte e tre le classi derivate hanno esattamente lo stesso codice ma una piccola differenza nel chiamare le funzioni membro dei rispettivi motori (questi motori hanno una classe separata).

Ad esempio, Ford chiama il codice della chiamata che è esattamente uguale alle altre due classi ma chiama qualcosa come ford_engine-> start() , ford_engine->clean() ecc.

//ly  honda  calls   honda_engine->start()   honda_engine->clean();

//ly  Audi calls audi_engine->start()  audi->clean();

Ora qui il problema è che ha un codice ridondante in tutti e tre i posti con una differenza minima. Come posso avere codice in un posto, molto probabilmente nella classe base e tutte le classi derivate usano lo stesso codice?

    
posta samprat 05.09.2014 - 00:45
fonte

2 risposte

1

L'idea è di aggiungere un motore di sola lettura protetto (ad esempio una proprietà protetta) alla tua superclasse. Quindi, ridefinire l'accessor nelle sottoclassi per restituire l'istanza del motore corretta. Il tuo codice diventa this->getEngine()->start() e così via.

    
risposta data 05.09.2014 - 01:37
fonte
4

Prima di tutto Ford , Honda e Audi probabilmente non essere classi derivate da auto . La derivazione dovrebbe riflettere le differenze nel comportamento a un livello astratto.

In questo caso, probabilmente ha più senso avere semplicemente un oggetto Car con un campo che identifica il produttore. Il Car possiede un motore, ma in un caso tipico, non è necessaria una classe diversa per ogni marca di motore; ad un livello astratto, il marchio è generalmente irrilevante.

Come tale, puoi avere qualcosa come:

class Car {
    class Engine {
        enum { diesel, piston, rotor, electric, hybrid } type;

        int HP;
        int torque;
        int max_rpm;

        bool running;

        void start() { running = true; }
        void stop() { running = false; }
        // ...
    } engine;

    std::string brand;
    std::string model;
};

In alcuni casi hai bisogno onestamente di modellare un motore a un livello di dettaglio in cui cose come l'ordine di accensione contano davvero, e avrai bisogno di molti più dettagli di questo. Dovrebbe comunque essere a livello comportamentale. Se avessi un Ford_motor rispetto a Honda_motor , il marchio dovrebbe essere ancora una mano breve per le differenze comportamentali. Vuoi davvero mantenere la visione più astratta possibile, quindi di solito vuoi modellare un motore (auto, ecc.) In termini di comportamento. La differenza tra un motore Ford e un motore Honda dovrebbe essere come una coppia più alta e l'altra linea rossa più alta rispetto all'altra; queste differenze possono essere modellate abbastanza facilmente fornendo parametri appropriati durante l'istanziazione dell'oggetto. Se Ford e Honda dovessero produrre motori con caratteristiche identiche (non solo energia, ma curve di potenza, ecc.), La differenza di marca è irrilevante per la tua modellazione.

Oh, e non dovresti non avere un getEngine come membro di Car . Una macchina è un'auto. ha un motore. Se fornisci un getEngine , dovrebbe essere un membro di AutoPartsStore o qualcosa del genere (ma a meno che tu non abbia a che fare con l'acquisto e la vendita di motori, probabilmente non dovresti avere una cosa del genere).

Quando una persona avvia la propria auto, non ottiene il motore e avvia il motore. Iniziano l'auto e dopo averlo fatto (con successo), la macchina è in esecuzione. Forzare un client a usare un getEngine e avviare il motore è sia schifoso da un punto di vista di codifica e da un punto di vista della modellazione - l'avvio della mia auto fa più rispetto all'avvio del motore. Controlla anche cose come alcune luci, la radio, il riscaldamento / l'aria condizionata e così via. Uno dei punti fondamentali della programmazione orientata agli oggetti è quello di proteggere il codice client dall'affrontare tutti questi dettagli interni, non per costringerli a gestire i dettagli e usa la sintassi crappy getXxx() per farlo!

    
risposta data 10.09.2014 - 08:27
fonte

Leggi altre domande sui tag