Nicht objektorientierte Programmierung in objektorientierter Sprache [geschlossen]

15

Kürzlich wurde mir die Aufgabe übertragen, einen Taschenrechner mit den Funktionen Addition, Subtraktion, Multiplikation, Division und Potenz mittels objektorientierter Programmierung zu erstellen . Ich habe diese Aufgabe erfolgreich abgeschlossen. Danach habe ich das gesamte Programm neu programmiert, ohne die objektorientierte Technik / Methode zu verwenden .

Die Sache, die ich bemerkte, dass meine Codelänge ziemlich stark reduziert wurde und es ziemlich verständlich war. Meine Frage hier ist also, wann ich objektorientierte Programmierung verwenden soll. Ist es in Ordnung, Programme ohne Objektorientierung in objektorientierter Sprache zu erstellen? Bitte helfen Sie mir dabei.

PS: Ich bitte hier nicht darum, mir die Vorzüge der objektorientierten Programmierung gegenüber der prozeduralen Programmierung zu erläutern.

FaizanRabbani
quelle
12
Es gibt absolut keinen Grund, die Anwendung verschiedener Techniken nach Bedarf zu vermeiden. Sie als Programmierer müssen die Vor- und Nachteile von Fall zu Fall abwägen. Sehr oft kommt es auf den persönlichen Stil an.
ChaosPandion
3
Ich hatte noch nie ein Problem damit. Die Sprache war in Anbetracht des Teams und / oder der anderen Architektur fast immer ein vorgeschriebenes Werkzeug.
8
Das gleiche Programm mit und ohne OO-Techniken zu implementieren ist eine gute Übung, um etwas zu lernen. Ich kann nicht verstehen, warum manche Leute hier dies zu leugnen scheinen oder Sie ablehnen. Das Problem bei Ihrer Frage ist jedoch, dass sie hier bereits mehrmals in verschiedenen Formen gestellt wurde. Und wenn Sie es leugnen, Sie werden fragen , über Verdienste der objektorientierten Programmierung über prozeduralen Programmierung. Und C ++ ist keine OO-Sprache, sondern eine Hybridsprache.
Doc Brown
3
Fügen Sie eine Funktion hinzu, die die von Ihnen eingegebene Formel anzeigt, und fügen Sie dann eine Quadratwurzelfunktion hinzu (Tun Sie dies nicht zuerst, das wäre Betrug.), Und teilen Sie uns Ihre Meinung mit.
JeffO

Antworten:

25

C ++ ist nicht "nur" eine OO-Sprache, sondern eine Multi-Paradigmen-Sprache. So können Sie sich für oder gegen OO-Programmierung entscheiden oder beides mischen. Die Verwendung von OO-Techniken verleiht Ihrem Programm mehr Struktur. Davon profitieren Sie, wenn Ihr Programm eine bestimmte Größe oder Komplexität erreicht. Diese zusätzliche Struktur ist jedoch mit dem Preis für zusätzliche Codezeilen verbunden. Daher ist es für "kleine" Programme oft der beste Weg, sie zuerst in einem Nicht-OO-Stil zu implementieren und später, wenn das Programm im Laufe der Jahre zu wachsen beginnt (was "wahrscheinlich nicht passieren wird"), immer mehr OO-Techniken hinzuzufügen "Programme, aber ist der typische Lebenszyklus für viele Business - Programme).

Der schwierige Teil ist, den Zeitpunkt nicht zu verpassen, an dem die Komplexität Ihres Programms die Größe erreicht, die mehr Struktur erfordert. Andernfalls erhalten Sie einen riesigen Haufen Spaghetti-Code.

Doc Brown
quelle
Wenn sich einfache "Übungs" -Programme zu entwickeln beginnen, ist es am besten, sie so zu implementieren, dass sie anschließend neu berechnet werden können. Vielen Dank für das Teilen :) +1
FaizanRabbani
@ CarlSmith: absolut. Aber als ich meine Antwort schrieb, versuchte ich mich auf die Punkte und den Umfang der eigentlichen Frage zu konzentrieren.
Doc Brown
10

Wie beurteilen professionelle Programmierer, ob sie sich für OOP entscheiden oder nicht? Es wäre sehr hilfreich für mich.

Für mich gibt es zwei Entscheidungspunkte. Erstens wird es manchmal am Anfang offensichtlich sein. Es wird viele ähnliche Typen geben, die gemeinsame Methoden verwenden, die sich in ihren Implementierungsdetails stark unterscheiden. Zum Beispiel baute ich ein Workflow-System auf und brauchte die Fähigkeit, beliebige Aufgaben zu implementieren. Um die Aufgabe auszuführen, implementierte ich eine Basisklasse, von der jede Aufgabe geerbt wurde, mit einer Execute()abstrakten Methode. Die übernehmenden Klassen lieferten die Implementierung, aber das Workflow-System konnte mit der Ausführung beginnen, ohne etwas über die Art der ausgeführten Aufgabe zu wissen.

Die meisten Projekte sind jedoch nicht so eindeutig. Der zweite Entscheidungspunkt ist, wenn eine Teilmenge des Projekts zu einem riesigen Gewirr von if-then-Anweisungen oder switch-case-Anweisungen herangewachsen ist, und insbesondere, wenn diese if-then-Anweisungen viel Setup-Code erfordern, um korrekt ausgeführt zu werden. Ich habe das Gefühl, dass ich allmählich die Logik dessen verliere, was ich erreichen will, und der Code fühlt sich anfällig an. An diesem Punkt ist es normalerweise ein Zeichen dafür, dass es Zeit ist, den Code mit bestimmten Implementierungen in Basisklassen umzugestalten.

Ein großer Teil des Wechsels zu einem objektorientierten Stil im Gegensatz zu einem funktionalen Stil besteht darin, If-Then-Anweisungen in Anweisungen zum Ausführen dieser Aktion zu konvertieren. Anstelle einer großen Menge von if-then-Anweisungen weisen Sie den Code einfach an, seine Aktion auszuführen. Welche Aktion tatsächlich ausgeführt wird, hängt von der von Ihnen bereitgestellten Implementierung ab.

Hier ist zum Beispiel der Funktionsstil im C # -Stil-Pseudocode:

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);
} 
...

Aber vielleicht könnten Sie das so umschreiben:

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
    }
} 

Und dann der Code selbst:

// 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);

Wenn das Wenn-Dann nur sehr wenig Code enthält, scheint dies eine Menge Arbeit zu bedeuten, um keinen Nutzen daraus zu ziehen. Und wenn das Wenn-Dann sehr wenig Code enthält, ist das richtig: Das ist eine Menge Arbeit für Code, der schwerer zu verstehen ist.

Aber der objektorientierte Stil leuchtet wirklich, wenn Sie mehr als eine Aktion haben als nur die Confirm()Methode, die ausgeführt werden muss. Möglicherweise verfügen Sie über eine Initialisierungsroutine, drei oder mehr auszuführende Aktionsmethoden und eine Cleanup()Methode. Der Basisalgorithmus ist identisch, mit der Ausnahme, dass seine Aufrufe an die entsprechenden Objekte gerichtet werden, die eine gemeinsame Basisklasse implementieren. Jetzt sehen Sie einen echten Vorteil für den objektorientierten Stil: Der Basisalgorithmus ist viel einfacher zu lesen, als wenn er bei jedem Schritt die if-then-Anweisungen überprüft.

Charlie Kilian
quelle
+1 für detaillierte Analyse. :) Ich habe ein paar Gedanken dazu.
FaizanRabbani
1
Abgesehen davon: bitte hör auf, "Danke" -Kommentare zu jeder Antwort zu posten. Wir konzentrieren uns lieber auf Fragen und Antworten, nicht auf Diskussionen.
Philip Kendall
5
Dieses Beispiel ist wichtiger als funktional.
OrangeDog
1
Nur eine Anmerkung: Wenn Sie sich zu einer Reihe von if / else- oder switch-Anweisungen neigen, ist es immer eine Option, eine Art Lookupt-Tabelle in Betracht zu ziehen. Also eine andere Möglichkeit zum Umschreiben, die nach dem Vorbild von var dict = new Dictionary<string,Action<UserInfo>{ { "email", callEmailFunction }, { "sms", callSmsFunction } }; dict[ action ]( userInfo );(dikt kann statisch sein, Fehlerbehandlung weggelassen)
stijn
3

Ja, es ist völlig normal, alten Code zu verwenden, vorausgesetzt, der Umfang Ihres Projekts ist bekannt oder begrenzt. Wenn Sie vorhaben, Ihr Programm oder Projekt zu erweitern, ist OOP eine Möglichkeit, da Sie Ihren Code nahtlos verwalten und erweitern können. Wenn Sie dies jedoch geplant haben und zu dem Schluss gekommen sind, dass Sie die Erweiterbarkeit des OOP niemals planen werden Projekt machen Sie dann das Schreiben von Code ohne OOP würde ausreichen. Es bedeutet nicht, dass Sie Ihr Projekt niemals aktualisieren können, wenn Sie einen Nicht-OOP-Ansatz verwenden, aber dann wäre es eine mühsame Sache. OOP soll uns dabei helfen, unser Konzept so zu visualisieren, als wäre es ein Organismus im wirklichen Leben, weil wir diese besser verstehen als alles andere.

user50927
quelle
1
"Es bedeutet nicht, dass Sie Ihr Projekt niemals aktualisieren können, wenn Sie einen Nicht-OOP-Ansatz verwenden. Dann wäre es jedoch mühsam.": OOP hilft bei der Erweiterung Ihres Projekts, wenn die meisten Erweiterungen das Hinzufügen neuer Klassen (z. B. Hinzufügen neuer Widgets zu eine GUI). Wenn die meisten Erweiterungen das Hinzufügen neuer Vorgänge umfassen, kann ein prozeduraler Entwurf effektiver sein.
Giorgio
1
Seit wann heißt "nicht objektorientiert" "alter Stil"?
DanielSank