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.