Programmazione non orientata agli oggetti in linguaggio orientato agli oggetti [chiuso]


15

Recentemente mi è stato assegnato il compito di creare una calcolatrice con funzioni di addizione, sottrazione, moltiplicazione, divisione e potenza mediante la programmazione orientata agli oggetti . Ho completato con successo questo compito. Tuttavia in seguito ho riprogrammato l'intero programma senza utilizzare la tecnica / metodo orientato agli oggetti .

La cosa che ho notato è che la lunghezza del mio codice è stata ridotta in modo significativo ed era abbastanza comprensibile. Quindi la mia domanda qui è quando dovrei usare la programmazione orientata agli oggetti? Va bene creare programmi senza Orientamento agli oggetti nel linguaggio orientato agli oggetti? Per favore, aiutatemi con questo.

PS: Non sto chiedendo qui di dirmi i meriti della programmazione orientata agli oggetti rispetto alla programmazione procedurale.


12
Non vi è assolutamente alcun motivo per evitare di applicare tecniche diverse, se necessario. Come programmatore dovrai valutare i pro ei contro caso per caso. Abbastanza spesso si riduce allo stile personale.
ChaosPandion,

3
Non ho mai avuto un problema. Il linguaggio era quasi sempre uno strumento prescritto dato il team e / o altra architettura.


8
L'implementazione dello stesso programma con e senza tecniche OO è un buon esercizio per imparare qualcosa, non riesco a capire perché alcune persone qui sembrano negare questo o sottovalutarti. Ma il problema con la tua domanda è che è già stato posto qui più di una volta, in forme diverse. E anche se si nega, si sta chiedendo circa meriti di Object Oriented Programming oltre programmazione procedurale. E C ++ non è un linguaggio OO, è un linguaggio ibrido.
Doc Brown,

3
Aggiungi una funzione che visualizza la formula che hai inserito e quindi aggiungi una funzione di radice quadrata (non farlo prima, sarebbe barare) e facci sapere cosa ne pensi.
JeffO,

Risposte:


25

Il C ++ non è "solo" un linguaggio OO, è un linguaggio multi-paradigma. Quindi ti consente di decidere a favore o contro la programmazione OO o di mescolarli entrambi. L'uso delle tecniche OO aggiunge più struttura al programma, di cui trarrai beneficio quando il programma raggiungerà una certa dimensione o complessità. Questa struttura aggiuntiva, tuttavia, ha il prezzo di righe di codice aggiuntive. Quindi, per i "piccoli" programmi, il modo migliore per procedere è spesso implementarli prima in uno stile non OO e aggiungere sempre più tecniche OO in seguito quando il programma inizia a crescere nel corso degli anni (che probabilmente non succederà all'esercizio " "programmi, ma è il tipico ciclo di vita di molti programmi aziendali).

La parte difficile è non perdere il momento in cui la complessità del programma raggiunge le dimensioni che richiedono più struttura. Altrimenti finirai con un enorme mucchio di spaghetti code.


Se i semplici programmi di "allenamento" iniziano a evolversi, il modo migliore è implementarli in modo tale da poter essere successivamente presi in considerazione. Grazie per averlo condiviso :) +1
FaizanRabbani il

@CarlSmith: assolutamente. Ma quando ho scritto la mia risposta, ho cercato di concentrarmi sui punti e sulla scala della domanda reale.
Doc Brown,

10

In che modo i programmatori professionisti fanno appello al giudizio sull'opportunità o meno di OOP? Sarebbe davvero utile per me.

Per me ci sono due punti decisionali. Innanzitutto, a volte sarà ovvio all'inizio. Ci saranno molti tipi simili che condividono tutti metodi comuni che differiscono ampiamente nei dettagli di implementazione. Ad esempio, stavo costruendo un sistema di flusso di lavoro e avevo bisogno della capacità di implementare attività arbitrarie. Per eseguire l'attività, ho implementato una classe di base da cui ogni attività ereditata, con un Execute()metodo astratto. Le classi ereditarie hanno fornito l'implementazione, ma il sistema del flusso di lavoro ha potuto iniziare l'esecuzione senza sapere nulla sul tipo di attività in esecuzione.

La maggior parte dei progetti non è così chiara. Il secondo punto decisionale è quando un sottoinsieme del progetto si è trasformato in un enorme groviglio di istruzioni if-then o istruzioni switch-case, e specialmente quando quelle istruzioni if-then richiedono molto codice di installazione per funzionare correttamente. Mi sento iniziando a perdere la logica di ciò che sto cercando di realizzare e il codice inizia a sembrare fragile. A quel punto, di solito è un segno che è tempo di refactoring del codice in classi base con implementazioni specifiche.

Una grande parte del passaggio a uno stile orientato agli oggetti invece di uno stile funzionale sta convertendo le istruzioni if-then in istruzioni "esegui questa azione". Invece di un enorme set di istruzioni if-then, basta dire al codice di eseguire la sua azione. L'azione effettivamente eseguita dipende dall'implementazione fornita.

Ad esempio, ecco lo stile funzionale nello pseudocodice in stile C #:

if ( action == "email" ) { 
    callEmailFunction(userInfo);
}
else if ( action == "sms" ) { 
    callSmsFunction(userInfo);
}
else if ( action == "web" ) { 
    endpoint = "http://127.0.0.1/confirm";
    confirmWeb(endpoint, userinfo);
} 
...

Ma forse potresti riscriverlo in qualcosa del genere:

interface IConfirmable {
    void Confirm(UserInfo userinfo);
}

public class ConfirmEmail : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmSms : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmWeb : IConfirmable { 
    // this is a constructor
    public ConfirmWeb(string endpoint) { 
        ...
    }

    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via web
    }
} 

E poi il codice stesso:

// An implementation that decides which implementation of the base class to use
// This replaces the if-then statements in the functional programmming.
IConfirmable confirmer = ConfirmerFactory.GetConfirmer();

// get the userinfo however you get it, 
// which would be the same way you get it in the functional example.
UserInfo userinfo = ...;

// perform the action.
confirmer.Confirm(userinfo);

Ora, quando c'è molto poco codice all'interno dell'if-allora, questo sembra un sacco di lavoro per non trarne alcun vantaggio. E quando c'è molto poco codice nell'if-allora, è corretto: c'è molto lavoro per il codice che è più difficile da capire.

Ma lo stile orientato agli oggetti brilla davvero quando hai più di un'azione che solo il Confirm()metodo che deve essere eseguito. Forse hai una routine di inizializzazione, tre o più metodi di azione che possono essere eseguiti e un Cleanup()metodo. L'algoritmo di base è identico, tranne per il fatto che effettua le chiamate negli oggetti appropriati che implementano una classe base comune. Ora inizi a vedere un vero vantaggio per lo stile orientato agli oggetti: l'algoritmo di base è molto più facile da leggere rispetto a se stesse controllando le istruzioni if-then in ogni fase del processo.


+1 per analisi dettagliate. :) Ho alcuni pensieri su questo.
Faizan Rabbani,

1
A parte: si prega di interrompere la pubblicazione di commenti "grazie" su ogni risposta. Preferiamo concentrarci solo su domande e risposte, non sulla discussione.
Philip Kendall,

5
Questo esempio è più indispensabile che funzionale.
OrangeDog,

Cf. il modello della catena di responsabilità .
Eric,

1
Solo una nota, quando ti inclini verso un mucchio di istruzioni if ​​/ else o switch, è sempre un'opzione da considerare una sorta di tabella lookupt. Quindi un altro modo di riscrivere che segue le linee di var dict = new Dictionary<string,Action<UserInfo>{ { "email", callEmailFunction }, { "sms", callSmsFunction } }; dict[ action ]( userInfo );(dict può essere statico, omessa la gestione degli errori)
stijn

3

Sì, è perfettamente normale utilizzare un codice vecchio stile, a condizione che l'ambito del progetto sia ben noto o limitato. Se hai intenzione di estendere il tuo programma o progetto OOP è una strada da percorrere, perché puoi mantenere ed estendere il tuo codice senza soluzione di continuità, d'altra parte se lo hai pianificato e sei giunto alla conclusione che non pianificherai mai l'estensibilità del sarebbe sufficiente un progetto realizzato, quindi scrivere codice senza OOP. Non significa che se usi un approccio non OOP non puoi mai aggiornare il tuo progetto, ma sarebbe una cosa noiosa da fare. OOP è per aiutarci a visualizzare il nostro concetto come se fosse un vero organismo di vita perché capiamo quelli meglio di ogni altra cosa.


1
"Non significa che se usi un approccio non OOP non puoi mai aggiornare il tuo progetto, ma sarebbe una cosa noiosa da fare.": OOP aiuta ad estendere il tuo progetto quando la maggior parte delle estensioni comporta l'aggiunta di nuove classi (ad esempio l'aggiunta di nuovi widget a una GUI). Quando la maggior parte delle estensioni prevede l'aggiunta di nuove operazioni, una progettazione procedurale può essere più efficace.
Giorgio,

1
Da quando "non è orientato agli oggetti" chiamato "vecchio stile"?
DanielSank,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.