Hallo,
der Titel sagt's eigentlich schon: Wieso Objektorientiert?
Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO
Programmierung anzufangen, bisher drücke ich mich (erfolgreich) um
dieses Thema und komme super zurecht.
Ich kann einfach keinen Vorteil für mich bzw. meine Programme sehen die
mir OO bringen würde. Warum sollte ich OO verwenden? Was bietet mir ein
Objekt, was nicht auch eine gute Funktion bietet?
Ich habe nun schon ein paar Bekannten diese Frage gestellt,
zufriedenstellend beantworten konnte sie aber niemand. Deshalb hoffe ich
auf euch!
Nur um irgendein Beispiel zu nennen:
Ich benutze seit Jahren meine UART Funktion und gebe sie auch gerne
anderen die diese einfach benutzen können. Wieso sollte man diese
Funktion nun OO umsetzen?
Den Code der Funktion selbst muss man, genau wie bei einem Objekt, weder
kennen noch verstehen. Die Funktion bekommt einfach gesagt was sie
machen soll, erneut wie bei einem Objekt. Was sie nun genau und vor
allem wie sie macht kann dem Anwender völlig schnuppe sein.
Funktion:
senden(Schnittstelle1, "Hallo Welt");
Objekt:
x = new senden();
x.schnittstelle(Schnittstelle1);
x.senden("Hallo Welt");
Genauso wie ich bei der Funktion kurz in den Kopf schauen muss um zu
sehen was ich übergeben kann/muss und was die Funktion genau kann, muss
ich in die Dokumentation der Klasse schauen um herauszufinden was diese
kann/benötigt.
Somit kommen wir wieder zur Eingangsfrage: Ich habe schon verstanden was
es mit Klassen, Vererbungen, etc. etc. auf sich hat, aber wo ist genau
der Vorteil zu Prozeduralen Programmen die aus Funktionen und Statischen
Elementen aufgebaut sind?
Ein Objekt kapselt nicht nur Funktionalität, sondern auch einen Zustand.
Das ist etwas was du ohne Objektorientierung nur schwer nachbilden
kannst. Ohne dieses wirst du schwerlich eine brauchbare Architektur auf
die Beine stellen können.
-Zusammenfassung von Datenstrukturen und den Funktionen, die auf ihnen
operieren
-Durch Vererbung Abbilden einer Hierarchie in der Software, wie sie der
realen Welt entspricht (z.B. Lassie ist ein Collie ist ein Hund ist ein
Säugetier ist ein Lebewesen...)
-Kapselung von Daten (man kann nicht direkt auf alles zugreifen, sondern
nur über vordefinierte Methoden)
Ovo schrieb:> Was bietet mir ein> Objekt, was nicht auch eine gute Funktion bietet?
Und ich glaube du hast da noch ein kleines Verständnisproblem. Ein
Objekt soll ja keine Funktionen ersetzen. Ganz im Gegenteil, ein Objekt
bietet selber Funktionen an (Methoden).
Wenn du ein Haus baust, willst du ja auch eine Küche, ein badezimmer,
einen Keller usw. haben. Oder würdest du einfachen einen 50m*50m*50m
Kubus hinklatschen, und da einfach alle Möbel reinschütten? ;-)
Du brauchst OOP normalerweise nicht bei Mikrocontroller-Steuerung,
Kommunikationsstack ...
Bei PC Programmen wo eher Daten verarbeitet werden oder grafischen Tools
schon.
OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von
beidem ist nicht viel zu halten.
Solange du keinen Säugetier-Zoo programmierst, ist prozedural genauso
gut.
Toni schrieb:> OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von> beidem ist nicht viel zu halten.
Völlig falsch, OOP ist viel älter als der Begriff "Extreme
Programming". Letztzeres wurde in der 90er Jahren definiert. OOP mit
Smalltalk gab es schon in den 70er Jahren.
Mark Brandis schrieb:> Völlig falsch, OOP ist viel älter als der Begriff "Extreme> Programming".
Ja ok hast recht.
Mark Brandis schrieb:> Eine grafische Benutzeroberfläche ohne OOP zu schreiben will sich wohl> niemand freiwillig antun ;-)
Eine GUI wird normalerweise nicht mehr "geschrieben".
Und ob ohne oder mit OOP macht keinen grundsätzlichen Unterschied.
Für "kleinere" Programme (d. h. z. B. im Embedded Bereich) mag ja das
prozedurale Vorgehen noch funktionieren. Schwierig wird es erst bei
komplexerer Software (z. B. PC-Anwendungen), in der viele Komponenten
zusammenspielen und zur Laufzeit hinzugefügt und entfernt werden. Ein
Softwarebiotop mit vielen verschiedenen Objekten, die zusammenspielen,
wird ohne objektorientierte Programmiersprache sehr schnell extrem
unübersichtlich. In prozeduralen Lösungen werden auch oft die
objektorientierten Konzepte ab einem bestimmten Komplexitätsgrad der
Software nachgebildet. Z. B. virtuelle Methodentabellen,
Datenbeziehungen, etc. Das geht natürlich auch, ist aber wesentlich
aufwändiger, da der OO-Verwaltungscode ja selbst geschrieben werden
muss. Das nimmt einem in der OO-Sprache der Compiler alles ab. Dadurch
wird der Code wesentlich schlanker und ist zielgerichteter formulierbar.
Prozedurale Lösungen werden dagegen oft im Embedded-Bereich bevorzugt,
weil dort strengere Vorgaben für Determinismus herrschen. Ein
dynamischer Objektverwalter für das Speichermanagement, der im
Hintergrund läuft, wie bei Microsoft.NET ist dort meist nicht
wünschenswert. Da ja z. B. sich der Motor am Controller weiterdreht und
nicht auf den Speichermanager warten kann (wie der Anwender vor dem PC
;-).
> Ohne dieses wirst du schwerlich eine brauchbare Architektur auf> die Beine stellen können
Auch wenn du es nicht glaubst weil du es nicht kannst,
ist das schon vielen Leuten vor dir gelungen.
> Eine grafische Benutzeroberfläche ohne OOP zu schreiben will sich wohl> niemand freiwillig antun ;-)
Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C
ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles
nicht-objektorientierte Programmiersprachen für die GUI, und die
nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows)
kann eher als bös gescheitere Katastrophe angesehen werden.
Toni schrieb:> OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von> beidem ist nicht viel zu halten.
Da spricht wohl der Profi. Auf die Begründung wäre ich gespannt.
Toni schrieb:> Solange du keinen Säugetier-Zoo programmierst, ist prozedural genauso> gut.
Was meinst du mit Säugetier-Zoo? Diese etwas praxisfremden Beispiele aus
Einführungen in die Objektorientierung? So nach dem Motto Ein Schimpanse
ist ein Affe ist ein Säugetier und erbt deshalb alles, was Säugetiere
und Affen können? Da geht es wirklich nur darum, Grundlagen zu
vermitteln. Praxisrelevante Beispiele sollen da nicht gezeigt werden.
Gut gemachte OOP hat insbesondere bei der Wiederverwendbarkeit und
Erweiterbarkeit von Code große Vorteile gegenüber rein prozeduralem
Code.
Einen guten Eindruck davon erhält man, wenn man sich mit
objektorientierten Entwurfsmustern beschäftigt und sich auch einige
konkrete Beispiele (z.B. die Stromklassen aus Java) anschaut.
Toni schrieb:> Eine GUI wird normalerweise nicht mehr "geschrieben".> Und ob ohne oder mit OOP macht keinen grundsätzlichen Unterschied.
Aber wenn du eine GUI "malst" wird im Hintergrund von deiner IDE Code
erstellt. Und dieser Code dürfte heute in den meisten Fällen
objektorientiert sein.
Viele Grüße
Michael
Ovo schrieb:> Funktion:> senden(Schnittstelle1, "Hallo Welt");>> Objekt:> x = new senden();> x.schnittstelle(Schnittstelle1);> x.senden("Hallo Welt");
völlig falsches Verständnis
OO:
Uart uart1 = new Uart(uartParameter1);
Uart uart2 = new Uart(uartParameter2);
uart1.sende(String1);
Byte[] vonU2 = uart2.empfange();
uart1.....
....
uart1.close();
...
Und OO ist noch viel mehr.
Michael Bertrandt schrieb:> Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C> ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles> nicht-objektorientierte Programmiersprachen für die GUI, und die> nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows)> kann eher als bös gescheitere Katastrophe angesehen werden.
C/Pascal (die anderen kenne ich nicht so genau) hindert dich nicht OOP
anzuwenden.
michael schrieb:> Stromklassen
???
Meinst du input und output Streams, dann noch die reader und writer
Klassen dazu, das ist das erste saubere und komplette Interface zur
exakten Trennung von Binärwerten und Character, das ich gefunden habe.
Michael Bertrandt schrieb:> Amiga (BCPL)
Intuition wurde nicht in BCPL geschrieben, sondern in C. Und Intution
war durchaus objektiorientiert. Nur weil die Sprache objektorientierte
Programmierung nicht unterstuetzt, muss man auf objektorientierte
Konzepte nicht verzichten. Das noch spaeter eingefuehrten BOOPSIE hat
das noch deutlicher gezeigt.
Diese ganzen Abgrenzungsdiskussionen sind sowieso idiotisch - ein guter
Entwickler bedient sich des Paradigmas, das zum Problem passt. Die
Uebergabe zwischen prozeduraler, modularer und objektorientierter
Entwicklung sind sowieso fliessend.
Michael Bertrandt schrieb:> Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C> ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles> nicht-objektorientierte Programmiersprachen für die GUI, und die> nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows)> kann eher als bös gescheitere Katastrophe angesehen werden.
von MFC mag man halten was man will. Aber mit .net kriegt man eine GUI
sicherlich leichter hin als direkt auf der Windows C-Api.
Udo Schmitt schrieb:> Meinst du input und output Streams, dann noch die reader und writer> Klassen dazu,
Genau das meine ich. Du kannst diesen Klassen leicht neue Funktionalität
hinzufügen, ohne dass du bestehenden Code ändern musst. Du musst einfach
einen neuen Decorator implementieren und auf bereits bestehende
Stream-Objekte anwenden. Leichte Wiederverwendung und Erweiterung, ohne
dass bestehender Code geändert werden muss.
http://de.wikipedia.org/wiki/Decorator
OOP:
Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört
mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code
braucht heutzutage sowieso keiner mehr.
Deine Funktion senden() ist schoen knapp bemessen. Ich brauche eine
Version mit einem Parameter fuer blocking I/O. Und natuerlich wirst du
auch noch eine Empfangsfunktion haben. Dann sieht das also so aus:
senden(Schnittstelle1, Blocking, "Hallo Welt");
empfangen(Schnittstelle1, Blocking, Buffer, BufferSize);
Irgendwie ungeschickt, wenn ich Funktionen habe, die irgendwas machen
und dann senden und empfangen aufrufen, aber nicht wissen, ob sie
blocken sollen oder nicht, muss ich diese Parameter auch mitgeben:
sendeHallo(Schnittstelle1, Blocking);
Besser, ich sammle die Optionen in einer Struktur:
struct Serial
{
Schnittstelle schnittstelle;
BlockingMode blockingMode;
}
Dann sehen senden und empfangen so aus:
Serial serial;
serial.schnittstelle = Schnittstelle1;
serial.blockingMode = Blocking;
senden(&serial, "Hallo Welt");
empfangen(&serial, Buffer, BufferSize);
sendeHallo(&serial);
Oder eben
Objekt:
Serial serial;
serial.schnittstelle = Schnittstelle1;
serial.blockingMode = Blocking;
serial.senden("Hallo Welt");
serial.empfangen(Buffer, BufferSize);
serial.sendeHallo();
Merke: Objekte sind oft naeher, als man denkt. Und auch billiger, als
man befuerchtet.
Toni schrieb:> OOP:> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code> braucht heutzutage sowieso keiner mehr.
OOP bringt zwangsläufig keinen zusätzlichen Overhead, vorallem wenn der
Compiler etwas vom Optimieren versteht. Man sollte sich allerdings
informieren wie die Sprache OOP technisch umsetzt um unnötigen Overhead
zu vermeiden.
Toni schrieb:> OOP:> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code> braucht heutzutage sowieso keiner mehr.
Man kann auch in Assembler wunderbar ineffizienten Code schreiben. Viele
Datenstrukturen lassen sich mit OOP wunderbar umsetzen. Bsp.: STL in
C++.
Und: Wenn mich ein wenig zusätzlicher Overhead wirklich nicht stört, ich
dafür aber viel schneller mit einem Programm fertig bin, dann
programmiere ich halt mit etwas Overhead.
Toni schrieb:> OOP:> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code> braucht heutzutage sowieso keiner mehr.
Du hast also keine Ahnung davon, aber du sagst erst mal das ist
Blödsinn.
Das gleiche mit "extreme Programming" davon weisst du wohl auch nicht
viel, schon mal 3 Monate ausprobiert?
Prima, mit der Einstellung würden wir heute immer noch in der Höhle am
Feuer sitzen und hätten noch nicht mal das Rad erfunden.
Ach so, das Feuer auch nicht, du müsstest deine Würmer also roh futtern
:-)
Es gibt mehrere Vorteile:
1. Vererbung
2. Überschreiben von Memberfunktionen
3. Templates
4. Operatordeklarationen
...
Der Unterschied zwischen OO und Funktionen liegt in der Kapselung des
gesamten Kontextes.
Ovo schrieb:> Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO> Programmierung anzufangen
nanana..
Du erwartest zum einen zu viel und hast zum anderen zu wenig
Vorstellung, wie sowas in der Praxis aussieht.
Also: erster Fall:
Objekte sind - um es mal salopp in plain C zu sagen - struct's, wo nicht
nur Daten, sondern auch Funktionspointer drinstehen. Das sind die sogen.
Methoden und so ein Konstrukt ist an einigen Stellen durchaus sinnvoll.
Stell dir mal vor, so eine Methode (bzw. in deiner prozeduralen Version
so eine Funktion) soll einerseits irgendwelche Daten errechnen und
andererseits ein Signal abgeben, ob dies geklappt hat oder nicht.
Natürlich kannst du ne Funktion schreiben
bool ErrechneEs (datentyp* MeineDaten);
und mit
if (ErrechneEs(&aktuelleDaten)) { ....
benutzen, wobei die Funktion über den Parameterzeiger die Daten schreibt
und als eigentliches Resultat true oder false zurückgibt. Problem dabei
ist die fehlende Kapselung, die bei etwas komplexeren Anwendungen
erfordert, daß man höllisch achtgeben muß, welche Funktionen wie und
wann auf welche Daten zugreifen dürfen oder nicht. Na klar, sowas geht,
aber es ist irgendwann stressig.
Mit einem Objekt (in C nachgebildet) sieht das ganz anders aus:
if (aktuelleDaten.ErrechneEs()) {...
womit ein Vertun beim Zuordnen von Daten und Funktion von selbst
vermieden ist.
Nächster Fall, Menüsysteme. Das ist der eigentliche Kernbereich für das
Verwenden von Objekten - jedenfall wenn man das "Geräte-Gesicht" in Form
eines bunten Bildschirms (TFT..) gestaltet hat. Dort müssen die
verschiedenen sichtbaren Elemente zum einen dargestellt werden und zum
anderen auf externe Einflüsse reagieren.
Natürlich könnte man die gesamte Darstellung in einer riesigen Funktion
unterbringen und auch das Reagieren auf Äußeres ebenfalls in einer
riesigen Funktion mit unzähligen if's und switch's, aber versuch mal,
bei so einer Implementation irgend eine Kleinigkeit ändern zu wollen -
da kriegst du ne Krise..
Also muß man es so halten, daß ein jegliches Element sich selbst
zeichnet und selbst auf Äußeres reagiert und dies auch von seinen
Subviews, also seinen enthaltenen Objekten erwartet. Da kommt dann das
Stichwort "Ereignisgesteuert" ins Spiel, was du bei deiner bisherigen
prozeduralen Programmierweise garnicht hattest. Aus äußeren
Veränderungen, also z.B. Benutzeraktionen oder daß eine bestimmte Zeit
verstrichen ist oder daß irgendein Teil des Gerätes jetzt ein Ergebnis
hat oder eine Position von einem Sensor erkannt wurde oder sonstwas
eben, wird eine Ereignis-Botschaft (ein Byte oder Word mit bestimmtem
Inhalt eben) generiert, die in eine Ereignis-Warteschlange (Ringpuffer)
eingereiht wird und ein anderer Teil der Firmware schaut regelmäßig nach
dieser Warteschlange und schmeißt etwaige Botschaften dem ganzen
Menüsystem in den Rachen. Diese leitet dann die Botschaft allen in Frage
kommenden Objekten zu und das, was sich dafür interessiert, mag es
auswerten und in seiner Weise drauf reagieren. Das ist ne ganz andere
Herangehensweise, als man es prozedural gewöhnt ist, also so, wie man
Programmabläufe auf der Wandtafel aufmalt.
Dein Problem sehe ich eigentlich nur darin, daß man in C keine Objekte
im Sprachumfang hat und sich deshalb selbst sowas konstruieren muß, und
daß man in C++ zwar Objekte haben kann, aber diese Spracherweiterung
eher krötig, noch schlechter lesbar als C und nicht wirklich nett
gemacht ist und man für Pascal, wo Objekte mittlerweile zum üblichen
Sprachumfang gehören und auch gut gemacht sind, für die Verwendung auf
µC zumeist keinen Compiler bekommt, diese Sprache also nicht wirklich
nutzen kann.
W.S.
Umgesetzt ist das einfach mit einem typedef-struct, das sowohl die
Einstellungen für dieses Objekt, als auch Zwischenergebnisse der
Funktionen (die einen Pointer auf die Struktur erhalten) enthält.
Das hab ich so gemacht, weil:
- Um mehr/weniger Drehgeber zu benutzen, muss ich nur eine zusätzliche
Struktur vom type "type_ROTARYENC" anlegen, die Parameter setzen und los
gehts. Sonst kein zusätzlicher Code
- Wo welcher Drehgeber angeschlossen ist etc., steht nicht in
irgendeiner ROTARYENC.h o.ä., sondern in meiner main.c
Vor allem der erste Punkt ist ein wirklich großer Vorteil. Deshalb hab
ich dieses System inzwischen auch übernommen für:
- LC-Displays mit HD44780 Controller
- Taster
- ADC (verschiedene Channels)
- Menüsteuerung
- System, mit dem Unterprogramme in regelmäßigen Abständen automatisch
aufgerufen werden (ein kleiner Hintergrund-Scheduler quasi, dort kann
man z.B. wunderbar die DREHGEBER_RUN(&device) eintragen)
Kurzfassung:
Den Sinn von Programmierparadigmen versteht man meist erst dann richtig,
wenn man selber ein größeres Stück Software damit geschrieben hat.
Ovo schrieb:> Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO> Programmierung anzufangen
Lass das sein: Ein Ruck bedeutet Gewalteinwirkung, und damit lernst du
OOP eher nicht.
Besser: Versuche einfach, deinen gewohnten Nicht-OO-Programmierstil
dahingehend zu verbessern, dass du auch größere Programme möglichst
übersichtlich gestaltest, duplizierten Code vermeidest und jedes Stück
Code so schreibst, dass du es später mit Erweiterungen an möglichst
wenigen Stellen für ähnlich geartete Aufgabenstellungen verwenden
kannst. Dann wirst du mit hoher Wahrscheinlichkeit ganz von selber und
sanft und gewaltfrei in die OOP hineingezogen werden.
Langfassung:
Wenn du andere fragst, warum sie OOP so toll finden, werden sie dir
entweder einen langen Vortrag über die theoretischen Hintergründe von
OOP halten, eine Marketing-Präsentation mit vielen Buzzwords geben, ein
paar einfache Beispiele nennen, die einzelne Aspekte von OOP beleuchten,
oder dir ein Monstersoftwareprojekt, bei dem sie OOP schon erfolgreich
angewandt haben, im Detail erklären.
Dem theoretischen Vortrag wirst du nicht folgen können, zumal es
wahrscheinlich gar nicht möglich ist, dei Vorteile von OOP rein
theoretisch abzuhandeln. Die Marketing-Präsentation wird sich vielleicht
gut anhören, am Ende wirst du aber nur wissen dass OOP ganz toll ist,
aber nicht warum. Bei jedem der einfachen Beispiele wird dir sofort
ein Weg einfallen, wie du die gleiche Funktionalität in Nicht-OOP
genauso einfach, wenn nicht sogar noch einfacher hinbekommst. Und bis er
dir das Monstersoftwareprojekt im Detail erklärt hat (wenn er sich dazu
überhaupt die Zeit nimmt), hast du garantiert den Spaß an der
Programmiererei (nicht nur der objektorientierten) verloren.
Nein, arbeite einfach an deinen Schnittstellenfunktionen weiter und
versuche sie zu verbesern und zu verallgemeinern, und habe kein
schlechtes Gewissen, weil alle anderen OOP machen und du nicht.
> bisher drücke ich mich (erfolgreich) um dieses Thema und komme super> zurecht.
Das ist ein sehr guter Ausgangspunkt.
> Funktion:> senden(Schnittstelle1, "Hallo Welt");
Ich nehme an, schnittstelle1 ist eine Schnittstellennummer o.ä.
Irgendwann möchtest du der Sendefunktion noch ein paar Parameter
übergeben, wie bspw. das von Fux genannte Blocking-Flag oder ein Enum
für das zu verwendende Hanshake-Verfahren (RTS/CTS, XON/XOFF usw.).
Damit die Argumentliste der Funktion nicht immer länger wird, und da
sich die Parameter zwischen zwei /senden/-Aufrufen sowieso nur selten
ändern, beschließt du, alle Parameter in eine Struktur zu packen und
diese als ein Argument zu übergeben. Da die Schnittstellennummer auch
nichts anderes als ein Parameter ist, packst du diese gleich mit in die
Struktur.
Deine Sende-Funktion sieht jetzt also etwa so aus:
Natürlich hast du auch eine empfangen-Funktion. Dieser wirst du
sinnvollerweise den gleichen Parametersatz übergeben. Weil du ein
ordentlicher Mensch bist, benennst du die Struktur von SendeParameter
gleich in SchnittstellenParameter um.
Irgendwann baust du in deine Schnittstellenfunktionen noch einen
FIFO-Puffer in Form eines Ringpuffers ein. Für die Pufferverwaltung
brauchst du einen Zeiger auf den Puffer selbst sowie einen Schreib- und
einen Leseindex, die zwischen zwei senden- oder empfangen-Aufrufen nicht
verloren gehen dürfen. Da du den Zeiger und das Indexpaar für jede
Schnittstelle brauchst, packst du sie einfach in die Parameterstruktur
mit hinein. Da diese jetzt mehr als nur Parameter enthält, benennst du
sie abermals um, nämlich einfach in Schnittstelle.
Mit der Struktur Schnittstelle hast du einen Datentyp geschaffen, der
alle wesentlichen Informationen über die Schnittstelle und deren
aktuellen Zustand enthält. Was liegt näher, als einen Zeiger auf diese
Struktur auch der Funktion für die Initialisierung der Schnittstelle zu
übergeben, so dass sie durch diese gleich mitinitialisiert wird.
Du wirst sicher noch ein weitere Schnittstellenfunktionen schreiben
(bspw. eine, die die aktuelle Anzahl der Bytes im FIFO-Puffer liefert).
Auch diesen neuen Funktionen übergibst du in bewährter Weise die
Struktur als erstes Argument, denn Kontinuität ist auch in
Computerprogrammen eine anzustrebende Eigenschaft.
Irgendwann wirst du auf die Idee kommen, ähnliche Funktionen auch für
die SPI-Schittstelle zu schreiben. Kein Problem, du erstellst einfach
eine Kopie aller Funktionen, passt ihren Inhalt etwas an und benennst
die Funktionen um, um zwischen den beiden Schnittstellentypen
unterscheiden zu können:
1
Alter Name Neuer Name Neuer Name
2
für UART für SPI
3
––––––––––––––––––––––––––––––––––––––––––
4
senden uartSenden spiSenden
5
empfangen uartEmpfangen spiEmpfangen
6
... ... ...
7
––––––––––––––––––––––––––––––––––––––––––
Kaum hast du das getan, fallen dir zwei Dinge negativ auf:
- Von dem kopierten Quellcode sind große Teile unverändert geblieben,
bspw. der gesamten FIFO-Pufferverwaltungscode. Tatsächlich geändert
hast du nur die Initialisierung der Hardware und den Code für das
Senden und Empfangen einzelner Bytes. Der ganze Rest liegt jetzt
dummerweise doppelt im Speicher.
- Wegen der Namensänderungen musst du die Namen zusätzlich auch bei
jedem Aufruf ändern.
Nach kurzer Überlegung kommt dir eine bessere Idee: Du machst die letzte
Aktion wieder rückgängig und baust stattdessen in die Intialisierungs-,
die Sende- und die Empfangsfunktion genau an den Stellen, wo UART- bzw.
SPI-spezifischer Code ausgeführt wird, jeweils eine Verzweigung ein.
Den Schnittstellentyp (UART oder SPI) schreibst du als Enum in die
Schnittstellenstruktur. Den gewünschten Schnittstellentyp übergibst du
anfangs der Intialisierungsfunktion, die ihn in die Struktur einträgt,
danach rufst du nur noch senden und empfangen auf ohne dich um den
Typ weiter kümmern zu müssen.
Damit kannst du sogar ein Programm mit nur einer einzigen kleinen
Änderung von UART- auf SPI-Kommunikation umstellen: Du musst lediglich
das entsprechende Argument beim Aufruf der Initialisierungsfunktion
ändern. Und das geht sogar zur Laufzeit.
Etwas weiter in die Zukunft denkend nimmst du eine Switch- anstelle der
If-Abfrage, um das Ganze künftig auf drei und mehr Schnittstellentypen
erweitern zu können.
Da mit jedem neuen Schnittstellentyp die einzelnen Funktionen immer
länger werden, beschließt du, die schnittstellenspezifischen
Programmteile in die separaten Funktionen
1
uartInitHW uartSendeByte uartEmpfangeByte
2
spiInitHW spiSendeByte spiEmpfangeByte
auszulagern und diese aus init, senden und empfangen per
Funktionszeiger aufzurufen. Für jeden Schnittstellentyp packst du die
drei Funktionszeiger in eine Struktur. Dann legst du ein Array an, das
für jeden Schnittstellentyp eine solche Struktur enthält. An den
Stellen, wo vorher noch die Unterscheidung mit den If- bzw.
Switch-Abfragen gemacht wurde, steht jetzt ein Zugriff auf das Array mit
den Funktionszeigerstrukturen und ein anschließender Funktionsaufruf
über einen dieser Funktionszeiger.
Um weitere Schnittstellentypen hinzuzufügen, brauchst du jetzt nur noch
folgende Dinge zu schreiben:
- die drei schnittstellenspezifischen Funktionen
- einen weiteren Eintrag in das Array mit den Funktionszeigerstrukturen
Die Funktionen senden, empfangen usw. brauchst du dazu überhaupt
nicht mehr anzufassen.
"Ist das nicht supercool?", wirst du dann sagen und nach diesem Erfolg
erst recht keinen Sinn mehr darin sehen, auf eine neues Paradigma wie
OOP umzusteigen.
Aber ohne es vielleicht bemerkt zu haben, steckst du bereits metertief
in der OOP drin.
Hoffentlich wird dies einer deiner Bekannten, der sich deinen Code
vielleicht einmal anschaut, erkennen und dir ein C++-Buch vorbeibringen.
Dort wirst du einen Aha-Effekt nach dem anderen erleben: Für vieles von
dem, was du in C unwissentlich objektorientiert programmiert hast, gibt
es in C++ eine knackigere Syntax (so genannten syntaktischen Zucker).
Das ganze Gedöns mit den Enums für die Schnittstellentypen und dem Array
mit den Funktionszeigerstrukturen übernimmt vollständig der Compiler für
dich.
Begeistert von diesen Dingen wirst du das Buch zu Ende lesen und noch
viele weitere Dinge finden, die in C++ leichter oder allgemeingültiger
zu schreiben sind als in C. Wenn du bspw. in C schon mit langen und
komplizierten Makros gearbeitet hast, wirst du feststellen, dass man die
entsprechenden Aufgabenstellungen in vielen Fällen sehr viel eleganter
durch so genannte Templates lösen kann.
1
Fazit: Vergiss erst einmal die OOP, programmiere einfach weiter mit
2
Begeisterung in C, der Rest kommt von selber.
BTW: Ich selbst bin nach ein paar Frusterlebnissen mit "erzwungenem" C++
auf ähnliche Weise zu "gemochtem" C++ gelangt.
Noch davor, während meines Studiums, wollte ich mir einen "Ruck" zur
funktionalen Programmierung (wieder ein anderes Paradigma) in Form von
Lisp geben, habe aber das Thema ziemlich bald wieder beiseite gelegt,
weil ich mich wie du gefragt habe: Warum das Ganze, was habe ich davon?
Man kann doch auch alles genauso gut in C oder einer Skriptsprache
machen.
Nachdem ich sehr viel später (und lange nach meiner Anfreundung mit der
OOP) festgestellt habe, dass meine (ebenfalls objektorientierten)
Python-Programme zunehmend Konstrukte der funktionalen Programmierung
enthalten (nicht weil ich funktional programmieren wollte, sondern weil
der Programmcode damit prägnanter und übersichtlicher aussah und ich
logische Fehler leichter entdecken konnte), habe ich angefangen, mich in
"richtige" funktionale Programmiersprachen einzuarbeiten. Und jetzt
macht es im Gegensatz zu den früheren Versuchen auch richtig Spaß.
1
Fazit 2 (die Verallgemeinerung von Fazit 1): Man sollte nicht zwanghaft
2
jedem Trend hinterherlaufen. Wenn der Trend wirklich gut ist, stößt man
3
früher oder später von selber und ganz zwanglos darauf.
Das war eine sehr ausführliche und besänftigende Antwort für den
Fragesteller, der offensichtlich bisher noch nicht vor der Bewältigung
größerer Softwareprojekte stand.
Bei einer ernsthaften Diskussion - die in diesem Thread wahrscheinlich
weder angebracht noch erwünscht ist - wäre aber anzumerken, daß die
Geschichte der technischen Entwicklung (und nicht nur diese) gezeigt
hat, daß es erheblich effizienter ist, auf das bereits vorhandene Wissen
und die Erkenntnisse anderer kompetenter Menschen aufzusetzen. Wollte
jeder jede sinnvolle Entwicklung selber bei Null beginnend
nachvollziehen, würden wir wohl heute eher am Lagerfeuer Pfeile
schnitzen als per elektronischer Kommunikation zu diskutieren.
OOP ist eine Mode, die schon eine Weile lang anhält.
Manch einer hat da früher drauf geschworen und ist froh, wieder
davon geheilt geworden zu sein. ;-)
Für manche Bereiche ist OOP aber auch gut geeignet,
für GUI-Progarammierung zum Beispiel.
Auch manche komplexe Problematik lässt sich mit OOP durchaus gut
abhandeln, nur der Hype ist reichlich übertrieben. Vieles wird auch sehr
bloatig durch OOP.
Funktionale Programmierung halte ich für wesentlich besser geeignet für
komplexe Software, besonders wenn die eingesetzten Programmiersprachen
starke Typsysteme haben (OCaml, Haskell).
O. schrieb:> Auch manche komplexe Problematik lässt sich mit OOP durchaus gut> abhandeln, nur der Hype ist reichlich übertrieben.
Da ist gar nichts dran übertrieben oder gehyped. Gute Konzepte setzen
sich durch, das war in der SE schon immer so. Für kleine Programme
braucht man OOP natürlich nicht. Und es gibt auch Software, da
funktioniert OOP nicht. In 95% aller Fälle ist OOP aber sehr gut
geeignet. Ich kenne kaum Software abseits der (E-)Technik, die nicht mit
OOP arbeiten, und das zurecht. Wer sein lebenlang mit C gearbeitet hat
kann oder will das wohl einfach nur nicht verstehen. Ich habe auch sehr
lange gebraucht, um zu erkennen das ich bspw. mit C# - das in meinen
Augen den OOP-Ansatz in Vollendung verfolgt - viel schneller gute
Software entwickeln kann als in C oder C++. Das ist einfach so. Wer in
privaten Projekten abseits von Microcontroller Spielerreien oder
OpenSource Kernelentwicklung noch C einsetzt, hat in meinen Augen
einfach nur ein Rad ab.
Wieso Objektorientiert?
Ich habe vor Jahrhunderten gelernt, dass objektorientiert
kleingeschrieben werden müsste, weil es ein Adjektiv ist. Aber das
scheint sehr sehr lange her zu sein.
qwewqeqwe schrieb:> noch C einsetzt, hat in meinen Augen> einfach nur ein Rad ab.
Das finde schlicht eine Frechheit, so eine Aussage zu machen.
Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß
ist OOP einzusetzen. Aber der Wahrheit letzter Schluss ist es nicht.
Wir haben uns in unserer Firma mal den Spass gemacht und haben einmal in
C# und ANSI C die identische Applikation geschrieben.
Das Ergebnis war sehr ernüchternd:
Die C# Anwendung war von der Codesize (Compilat) 40% größer als die ANSI
C Anwendung.
Was im ersten Moment nichts zu sagen hat.
Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies
betraf die GUI und Berechnungen.
Von der Ladezeit ganz zu schweigen.
Sicher gibt es Anwendungen bei denen OOP Vorteile hat.
Aber allgemein zu sagen, dass C Müll ist, ist nicht korrekt.
Wusstet ihr eigentlich, dass schon Anfang der 70er IBM auf der /370 OO
programmiert hat?
Und man muss nicht alles mitmachen, was einem Mickysoft vor die Füße
schmeißt.
MAD (Gast) schrieb:
qwewqeqwe schrieb:
>> noch C einsetzt, hat in meinen Augen>> einfach nur ein Rad ab.> Das finde schlicht eine Frechheit, so eine Aussage zu machen.> Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß> ist OOP einzusetzen.
OOP ein "Muß" für Windows? Wie kommst du denn darauf? Das Windows-OS
selber, d.h. die Anwender-Applikationsschnittstelle das sog. Win32-API
ist NICHT objektorientiert. Die kannst du auch heute noch mit ganz
stink-ordinärem C-Code anprogrammieren ("Methode" Charles Petzold). C#
macht unter der Haube auch nichts anderes als Win-API Funktionen
aufzurufen. Auch wenn C# selber mit Objekten hantiert (jedenfalls darauf
ausgelegt ist), die der Anwender sich baut und anschließend instanziert.
OOP gab es vergangentlich (und gibt es noch immer) in Windows auch mit
Hilfe der seit Jahren vorhandenen Klassenbibliothek MFC (Microsoft
Foundation Classes), die mal ins Leben gerufen wurde, um C++
Software-Systeme in OOP unter Windows realisieren zu können. Aber auch
MFC-Code ruft - wenn das OOP C++ Programm einmal kompiliert und
gestartet wurde - ihrerseits nur wieder die bekannten Win32-API
Funktionen auf. Ganz genau so als wenn sie aus einem prozeduralen
C-Programm kämen.
Herr werfe Hirn schrieb:> OOP ein "Muß" für Windows? Wie kommst du denn darauf? Das Windows-OS> selber, d.h. die Anwender-Applikationsschnittstelle das sog. Win32-API> ist NICHT objektorientiert.
Bis Windows 7 mag das gestimmt haben. Seit Windows 8 ist die Winapi aber
auch objektorientiert.
MAD schrieb:> Das Ergebnis war sehr ernüchternd:> Die C# Anwendung war von der Codesize (Compilat) 40% größer als die ANSI> C Anwendung.> Was im ersten Moment nichts zu sagen hat.> Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies> betraf die GUI und Berechnungen.> Von der Ladezeit ganz zu schweigen.
Solche Beispiele sind wenig Zweckdienlich. Wenn jemand keine Ahnung von
C# oder OOP im Allgemeinen hat, bringt es natürlich auch nix "mal eben
was auszuprobieren". Meine Erfahrungen haben nämlich genau das Gegenteil
gezeigt.
O. schrieb:> Funktionale Programmierung halte ich für wesentlich besser geeignet für> komplexe Software, besonders wenn die eingesetzten Programmiersprachen> starke Typsysteme haben (OCaml, Haskell).
Schön, dass du das so siehst. Komisch nur, dass 99% der
Software-entwickelnden Industrie das anders sieht. Meinst du wirklich
die würden nicht auf funktionale Sprachen setzen, wenn die so viel
besser geeignet wären?
Ich vermute daher eher, dass du mit deiner Aussage daneben liegst.
res schrieb:> Bei einer ernsthaften Diskussion - die in diesem Thread wahrscheinlich> weder angebracht noch erwünscht ist - wäre aber anzumerken, daß die> Geschichte der technischen Entwicklung (und nicht nur diese) gezeigt> hat, daß es erheblich effizienter ist, auf das bereits vorhandene Wissen> und die Erkenntnisse anderer kompetenter Menschen aufzusetzen. Wollte> jeder jede sinnvolle Entwicklung selber bei Null beginnend> nachvollziehen, würden wir wohl heute eher am Lagerfeuer Pfeile> schnitzen als per elektronischer Kommunikation zu diskutieren.
Meinem obigen Beitrag soll keineswegs dazu führen, dass jetzt jeder
Neuling die OOP von Grund auf neu erfindet. Ich bin aber der festen
Überzeugung, dass der Einstieg leichter vonstatten geht, wenn die
Motivation dazu von innen und nicht von außen kommt. Und das geschieht
im Fall des TE (und vielen anderen in der gleichen Situation) nicht
dadurch, dass man sich ohne sichtbare Notwendigkeit ein tausendseitiges
OOP- oder C++-Buch hineinzieht, sondern vielmehr schrittweise:
1. Man sammelt erst einmal in der bereits gewohnten Programmiersprache
viel Erfahrung, insbesondere auch negative.
2. Ist man mit Motivation bei der Sache, versucht man ganz automatisch,
die negativen Erfahrungen durch bessere Programmiertechniken in der
gleichen Sprache kompensieren. Solche Programmiertechniken kann
man entweder selber ausbrüten, im Code von anderen entdecken oder
durch entsprechende Anfragen in Foren (wie z.B. diesem hier) gezeigt
bekommen.
3. Wer mit halbwegs offenen Augen durchs Leben geht und hin und wieder
einen Artikel über OOP liest, stellt fest, dass die eine oder andere
der in Schitt 2 gefundenen Programmiertechniken stark in Richtung OOP
zielt und in einer entsprechenden Programmiersprache viel leichter
umzusetzen ist. Vielleicht wird man aber auch in der Antwort auf eine
Forenanfrage darauf hingewiesen, dass das vorliegende Problem sehr
viel eleganter in einer OO-Sprache gelöst werden kann.
4. Der Lernende hat bis dahin die OOP keineswegs neu erfunden, sondern
allenfalls etwas an der Oberfläche gekratzt. Aber jetzt ist die
Motivation da, sich mit der OOP intensiver zu beschäftigen. Jetzt
wäre es unsinnig, neue Programmiertechniken weiterhin komplett selber
erarbeiten zu wollen. Deswegen ist jetzt ist auch der richtige
Zeitpunkt, die tausendseitigen Bücher in Angriff zu nehmen und
dadurch mit dem OOP-Aufzug steil nach oben zu fahren.
Aber erst jetzt.
Die Leute, die diesen Prozess nicht durchgemacht haben, sondern die OOP,
ohne die Erfahrungen in Punkt 1 gesammelt zu haben, im Rahmen von
Lehrveranstaltungen eingehämmert bekommen, erkennen die Vorteile der OOP
i.Allg. nicht und neigen deswegen dazu, ihren Code in völlig unsinnige
Klassenstrukturen zu pressen, nur um das Ganze objektorientiert aussehen
zu lassen.
Es kann sehr gut sein, dass Leute, die das Programmieren nicht in einer
prozeduralen, sondern gleich in einer objektorientierten Sprache lernen,
dieses Problem nicht haben. Der TE gehört aber definitiv nicht zu dieser
Gruppe.
O. schrieb:> OOP ist eine Mode, die schon eine Weile lang anhält.
Keine Angst, sie wird auch weiterhin anhalten. Genauso wie die OOP die
strukturierte Programmierung nicht verdrängt hat, werden kommende
Programmierparadigmen die OOP nicht verdrängen. Ich kann mir allenfalls
vorstellen, dass in Aufgabendomänen, in denen es kaum natürliche und
offensichtliche Objektstrukturen gibt (davon gibt es genügend), die OOP
etwas in den Hintergrund treten wird.
> Funktionale Programmierung halte ich für wesentlich besser geeignet für> komplexe Software, besonders wenn die eingesetzten Programmiersprachen> starke Typsysteme haben (OCaml, Haskell).
Das wird auch ganz sicher ein Thema der nächsten Jahre sein. Schon jetzt
werden gängige imperative Programmiersprachen (bspw. Python, C#, Java,
C++11 usw.) zunehmend mit funktionalen Konstrukten gespickt. Haben die
Leute erst einmal Zucker geleckt, wagen sie irgendwann den Schritt nach
F# oder OCaml wagen, um dann noch etwas später bei Haskell o.ä. zu
landen. Zusätzlichen Auftrieb für die FP kommt von den immer mehr an
Bedeutung gewinnenden Multiprozessorsystemen, die damit leichter zu
programmieren sind.
Das alles ist aber ein langsamer, stetiger Prozess, wie auch bei der
OOP, die ja auch ein paar Jahrzehnte brauchte, um sich durchzusetzen.
Langfristig wird die imperative Programmierung (zu der auch die OOP
gehört) generell etwas an Boden verlieren (aber keineswegs aussterben),
da mit der ins Unermessliche steigenden Komplexität der Softwaresysteme
die Codeverifikation (nicht die vollautomatische, auf die wir wohl noch
eine Weile warten müssen, sondern vor allem die toolgestützte manuelle)
immer wichtiger wird. Deklarative und insbesondere funktionale Programm
lassen sich aber i.Allg. leichter und vor allem gründlicher verifizieren
als imperative.
> > Auch manche komplexe Problematik lässt sich mit OOP durchaus gut> > abhandeln, nur der Hype ist reichlich übertrieben.> Da ist gar nichts dran übertrieben oder gehyped. Gute Konzepte setzen> sich durch
Es gibt sehr viele Programme, denen man ansieht, daß der Anwender es mit
dem objektorientierten übertrieben hat, und Strukturen eingeführt hat,
die den Aufwand erhöhen, die Übersichtlichkeit reduzieren, bloss weil er
dem Hype des objektorientierten Programmierens erlegen ist.
Du wirst zu denen gehören.
Hallo Ovo,
Ovo schrieb:> Programmierung anzufangen, bisher drücke ich mich (erfolgreich) um> dieses Thema und komme super zurecht.
Es mag durchaus sein, dass für deine Anwendungen OOP nicht geeignet oder
notwendig ist. Wenn das der Grund für's Rumdrücken ist, dann ist das ein
guter Grund.
OOP kann einem bei vielen, vor allem komplexeren Problemstellungen aber
sehr helfen, einen klaren Kopf zu behalten. Ein Beispiel: Die Vererbung
hilft dir, bei verwandten Klassen die gleichen Methoden zu haben. Das
erspart dir einiges an Koordinationsarbeit und Kurzzeitgedächtnis.
OOP ist ein Werkzeug, keine Religion.
Ein tieferer Blick in die OOP zwecks legaler Bewusstseinserweiterung ist
auf jeden Fall lohnenswert.
Weil hier von MFC dir Rede war. MFC ist das beste Beispiel dafür was
dabei raus kommt, wenn man C Programmierer zwingt, mal schnell ein
Framework in C++ zu entwickeln, die aber gar keine Ahnung von
objektorientierter Programmierung und C++ haben.
An alle OOP-Ablehner: versucht doch mal ein Ringpuffer zu programmieren,
der mehrfach im Programm verwendet werden kann und das auch noch mit
verschiedenen Datentypen. Spätestens dann sollte auch dem letzten klar
werden, warum OOP und templates erfunden wurden.
Ich stimme Dir zu, daß es befriedigender und freudespendender sein kann,
durch eigene Erfahrungen Wissen zu erlangen.
Es erfordert nur erheblich mehr Zeit.
Es hängt dabei natürlich von der eigenen Zielsetzung und den Aufgaben
ab, ob man etwa nur aus persönlicher Neugier mal ein Programm schreiben
will, oder vielleicht sogar beruflich Software-Entwicklung betreiben
will.
Bezogen auf das Thema OOP würde man beispielsweise durch die
Bereitschaft, sich dem aktuellen Wissenstand theoretisch zu nähern,
viele Fehler vermeiden können, die sich in den vergangenen Jahren im
Überschwang der ersten Begeisterung gezeigt haben. (Übertriebene
Vererbungshierarchien statt Aggregation, Verdammung von "Non-member
functions" u.v.m.)
Möglicherweise kommt man auch über den "steinigen" Weg zu einem
sinnvollen (nicht: "aus Prinzip ist alles ein Objekt") Einsatz moderner
Methoden der Software-Entwicklung unter Verwendung der jeweils passenden
Werkzeuge.
Die Zurkenntnisnahme der zur Verfügung stehenden Erfahrungen ist dabei
aber sicher hilfreich.
MAD schrieb:> Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß> ist OOP einzusetzen.
So ein Schmarn.
Erstens ist es kein muss, zweitens: Auch unter Linux ist der OOP Ansatz
mehr als verbreitet. Fast jede Anwendersoftware und Spiele sowieso bauen
auf OOP. Der Nachfolger von XServer - Wayland - setzt deswegen auf C++
statt auf C. Selbst die Programme die C einsetzen, benutzen dazu einen
Pseudo-OOP Ansatz. Siehe z. B. Gnome was ja bekanntlich auf GTK+ basiert
und dazu sein eigene Art Framework bereitstellt.
MAD schrieb:> Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies> betraf die GUI und Berechnungen.> Von der Ladezeit ganz zu schweigen.
Das sind private Spielerreien ohne wirklich relevante Aussagekraft. Wer
Anwendersoftware für halbwegs aktuelle PC's und Systeme schreibt, den
bringen die angeblichen 20% so gut wie gar nichts - weil sie außer im
Benchmark - wenn überhaupt - nicht bemerkbar sind. Selbst Java
Anwendungen laufen performant genug um nicht auf C zu setzen.
MAD schrieb:> Aber allgemein zu sagen, dass C Müll ist, ist nicht korrekt.
Ich sage nicht das C Müll ist, sondern das es bescheuert ist C - vor
allem in privaten Projekten - einzusetzen wenn es Aufgrund der
Hardwarebedingungen kein Muss ist.
Das kannst du meinetwegen als Frechheit betiteln. Wenn jemand seinen
Rasen mit eine Sense mäht statt mit einem Rasenmäher würdest du aber die
selbe Aussage treffen.
Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen
vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet.
Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.
Alexander T.-Z. schrieb:> OOP ist ein Werkzeug, keine Religion.
Meinst du? Es gibt doch schließlich OOP-Handwerker und OOP-Prediger?
Dieser S. schrieb:> Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen> vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet.> Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.
Ich muss dir leider mitteilen, dass auf meinem Rechner von den 1389
Executables in /bin und /usr/bin kein einziges ein C++-Programm ist.
Sorry!
Konrad S. schrieb:> Alexander T.-Z. schrieb:>> OOP ist ein Werkzeug, keine Religion.>> Meinst du? Es gibt doch schließlich OOP-Handwerker und OOP-Prediger?>> Dieser S. schrieb:>> Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen>> vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet.>> Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.>> Ich muss dir leider mitteilen, dass auf meinem Rechner von den 1389> Executables in /bin und /usr/bin kein einziges ein C++-Programm ist.> Sorry!
Installiert man sich heutzutage einen Linux-Arbeitsrechner, sind immer
OOP Anwendungen dabei. Und wenn es kein C++ ist dann sinds in C
geschriebene auf GTK+ basierende Programme. Sorry!
@Dieser S.
Klar gibt es da OOP-Anwendungen. Dann zähl mal. Bin gespannt, viewiele
du findest. Und setz das ins Verhältnis zu den nicht OOP-Anwendungen. Da
wirst du bei deiner Aussage deutliche Abstriche machen müssen.
Konrad S. schrieb:> Und setz das ins Verhältnis zu den nicht OOP-Anwendungen.
Blödsinnige Aussage.
Nachdem OO bei großen Programmen sinn macht, es aber viele kleine und
deutlich weniger große gibt, ist die nackte Anzahl ein unsinniger Wert.
Konrad S. schrieb:> @Dieser S.> Klar gibt es da OOP-Anwendungen. Dann zähl mal. Bin gespannt, viewiele> du findest. Und setz das ins Verhältnis zu den nicht OOP-Anwendungen. Da> wirst du bei deiner Aussage deutliche Abstriche machen müssen.
Wir reden hier die ganze Zeit von OOP Anwendungen für Endanwender. Das
Systemprogramme da nicht zugehören ist wohl logisch oder? Obwohl Gnome
und KDE bspw. auch OOP benutzen :) . . .
Nenn mir doch mal ein paar große Programme für Endanwender in Linux, die
kein OOP benutzen. Gimp, LibreOffice, FileZilla, Thunderbird, Firefox.
Ja selbst Anjuta und KDevelop. Alles Programme die auf OOP setzen. Bin
gespannt.
> Nachdem OO bei großen Programmen sinn macht
Nun widersprichst du aber all den Verfechtern hier,
die meinen, OOP macht immer Sinn, bei jedem Programm
zumindest bei jedem Programm für ein GUI.
Ja ja, die Beliebigkeit der Behauptungen.
> von MFC mag man halten was man will.
Aha, wenn dir die Schlüsse nicht gefallen, dann zieht man mal eben die
Aussagekraft in Zweifel.
> Aber mit .net kriegt man eine GUI> sicherlich leichter hin als direkt auf der Windows C-Api.
Schönes Beispiel, denn eines der ganz Wenigen, bei denen ein Programm
nicht anhängig von Zeit und Historie und Zufall in einem System
geschrieben wurde, sondern zwei quasi funktionsgleiche Programme,
PaintShop und Paint.NET, welches eine fast exakte Kopie von PSP4 ist,
sich gegenüberstehen, das eine auf WinAPI, das andere mit DotNET
erstellt, und der Vergleich geht 100 Prozent zu Gunsten von PaintShop
aus. Wie man beispielsweise daran sieht, daß man bei DotNET einfach man
die gradweise Drehung des Bildes weggelassen hat, weil man nicht in der
Lage war, ihn zu realisieren.
Immer wieder fanzinierend wie ein Programmierparadigma gegen ein anderes
in "Stellung" gebracht wird.
Man kann auch hingehen und für jedes seiner eigenen Probleme jeweils
eine eigene Programmiersprache erstellen die genau das Problem
beschreibt und damit löst.
Wer nicht verstanden hat worin die Vorteile von Kapselung und Vererbung
bestehen kann nicht darüber urteilen ob es "besser" oder "unsinnig" ist.
Wenn man von Anfang an OO verfolgt hat man, wie hier schon einige
Beispiele genannt wurden, weniger Arbeit und es ist übersichtlicher und
somit wartbarer.
Wer natürlich lieber "Russencode" in einer einzigen Zeile ohne Kommentar
und mit sich selbst ändernden Opcodes bevorzugt soll das tun, aber
nachher nicht hier ankommen und verlangen das das mal einer debuggt
weil's auf dem neuen µC nicht mehr geht da der Hersteller inzwischen die
Register und Opcodes geändert hat ...
Und Microsoft als schlechtes Beispiel angeben ist zu einfach, wenn ich
noch an TAPI denke wird's nur lächerlich da wurde damals (TM) im
Developernetwork doch tatsächlich der ursprüngliche C-Code mit allen
Fehlern 1:1 einfach gekapselt und dann als Ultima Ratio verkauft.
Man muß also zwischen Marketing und realer Programmierung unterscheiden.
Wer abstrakter vorgehen will kann sich ja mal UML ansehen, das wurde
entwickelt um die Hausfrau von nebenan "ganz einfach" zur
Topprogrammiererin zu machen hat aber ebenfalls viele Schwächen.
Egal wer was behauptet wenn jemand OO erlernen will hat er nachher mehr
Vorteile als Nachteile.
Wer seinen µC aus dem FF kennt und nur diesen einen bedienen will/muß
kann auch hardwarenah in Assembler programmieren.
Nur macht es keinen wirklichen Unterschied ob ich in Assembler, C oder
C++ programmiere, der Compiler erledigt mir mehr Optimierungen als ich
für verschiedene Hardware jemals selber erlernen kann.
Diese Diskussion ist daher mit der zwischen Assembler vs. Hochsprache
identisch und genauso sinnfrei.
Wer kein OO will soll es bleiben lassen aber OO nicht herunterputzen
weil man's entweder nicht verstanden hat oder der Meinung ist es gibt
keine Vorteile.
Wer schonmal mehrere 10000 Zeilen Code debuggt hat wird sicherlich
erkennen das wenn's im Objekt XYZ kracht man da viel einfacher
Breakpoints setzen kann als wenn alles über hunderte von Zeilen verteilt
ist.
Kapselung ist nunmal das Credo ;-)
Konrad S. schrieb:> @Jeje> Mein gerade laufender Firefox bindet 162 Libraries ein. Davon sind 154> C-Libraries. Soviel dazu.
Wozu? Es zeigt das OOP so gut wie in jedem Programm Sinn macht. Nichts
für ungut :)
... schrieb:> Wie hast du rausgefunden, das es C Liberaries sind. Doch hoffentlich> nicht über die Schnittstelle, oder?
Wenn eine Library (auch) gegen die libstdc++.so gelinkt ist, dann werte
ich die Library als OOP. Ist sie nur gegen die libc.so gelinkt, dann
werte ich sie nicht als OOP. Einige in C geschriebene GUI-Libs sind
natürlich vom Design her OOP und gehen mir mit dieser Zählweise durch
die Lappen.
MaWin schrieb:> Wie man beispielsweise daran sieht, daß man bei DotNET einfach man> die gradweise Drehung des Bildes weggelassen hat, weil man nicht in der> Lage war, ihn zu realisieren.
Kann es daran liegen, dass die Funktion in Paint.NET im Menü Ebenen ->
Rotationszoom zu finden ist und nicht im Menü Bild?
Oder liegt es daran das jemand Graphics.DrawImage aufruft und
Graphics.RotateTransform nicht kennt bzw. bei WPF Media.Transform nicht
kennt...
Konrad S. schrieb:> @Jeje> Mein gerade laufender Firefox bindet 162 Libraries ein. Davon sind 154> C-Libraries. Soviel dazu.
Das ändert ja nichts daran das Firefox im OOP Ansatz programmiert wurde
augenroll . . .
Naja, der Thread zeigt es ja nur zu deutlich. Jeder versteht darunter
etwas anderes und alleine beim Durchlesen der ganzen Kommentare stellt
sich auch mir mehr und mehr die Frage, was Objektorientierung denn nun
tatsächlich ist. Ob es sinnvoll ist und ob man es tatsächlich benötigt.
Ich persönlich würde sagen, es ist eine Modeerscheinung, die sich als
Selbstläufer etabliert hat. Genauso wie damals eine bekannte
Programmiersprache, die eigentlich erschaffen wurde um
Betriebssystemkerne und Gerätetreiber zu programmieren, mit der aber
plötzlich ganze Anwendungen geschrieben wurden. Selbst ihre Erfinder
waren damals äußerst erstaunt darüber und konnten es nicht fassen. Aber
sie haben den Quatsch mitgemacht denn wer verhindert schon seinen
persönlichen Erfolg, nur weil er den Eindruck hat, dass das, was er
persönlich geschaffen hat, plötzlich zweckentfremdet verwendet wird.
Später wurde dann noch eine "objektorientierte" Variante dieser tollen
Programmiersprache entwickelt (was immer das sein mag ...)
Ich hatte damals diese ganze Sache selbst miterlebt und kann auch heute
nur noch den Kopf schütteln. Gottseidank gibts auch heute noch andere
richtig gute Programmiersprachen. Die liegen zwar nicht so im Trend und
sind eher was für Kenner und Liebhaber, die wissen, womit sie sich
beschäftigen ;-)
Aber zurück zum Thema.
http://www.objektorientierung.net/
Jedem Tierchen sein Pläsierchen ;-)
Gruß, Norbert
Norbert schrieb:> http://www.objektorientierung.net/
Aua. Was dieser Mensch da von sich gibt ist ja haarsträubend. Aber sehr
unterhaltsam ^^
Erinnert mich ein bisschen an diesen Blog über die schädliche Wirkung
von Barcodes, die aufgrund ihres wilden Schwarz-weiß-Musters böse
Energien erzeugen sollen.
>/www.objektorientierung.net/
bietet er/sie dann auch eine LÖSUNG ,oder werden nur die "Probleme"
aufgezeigt?? (Jammer kann jeder ;-)
wenn man mal über den "C"-Tellerrand" schaut: z.b. auf DELPHI:
Componenten/Controls (VCL), JCL, Indy, Virtualtreeview, SynEdit,
schlagmichtot....
ich GLAUBE nicht, dass es z.Z: in diesem Bereich irgend eine besser
Lösung als Klassen/Objekte gibt
(also dort wo seine eigene Arbeit, auf der anderer aufbaut, (abgeleitete
Klassen))...
ABER: natürlich ist das nicht DIE Lösung für alles..
>Ich persönlich würde sagen, es ist eine Modeerscheinung,
von "Interfaces" könnte man das vielleicht behaupten, deren Boom ist
IMHO inzwischen wieder etwas abgeflacht, ..
Ich denke, dass man dem Thema nicht gerecht werden kann, wenn man nur
die Programmierung ansieht. Schlussendlich ist "objektorientiert" auch
noch OOA. Damit bekommt man (zum Beispiel mit UML) ein sehr mächtiges
Werkzeug in die Hand.
Grüsse,
René
Hallo,
ich habe nun lange still mitgelesen und mich über eure (zahlreichen –
danke!) Beiträge gefreut.
Kurz vorweg, der Preis für den besten Beitrag des Jahres darf gerne an
Yalu X. (yalu) (Moderator) gegeben werden. Einfach ein sehr guter und
nachvollziehbarer Beitrag. Super!
Wie es weiter geht:
Nun ich denke ich bleibe, wie einige es auch vorschlugen, bei meinen
„Leisten“. Gleichzeitig möchte ich mich nun aber, aus reinem Interesse
und nicht der Notwendigkeit halber, mit dem Thema befassen. Denn das
Phänomen, welches Yalu beschrieb ist korrekt. Man feilt gerne an seinen
Funktionen herum um noch ein extra mehr mit einzubinden oder die
Kompatibilität zu erhöhen. Ich denke, ich kann mit eine Co-Existenz
beider Philosophien vorstellen - wer weiß, vielleicht gefällt es einem
am Ende ja?
Am Ende kann man sicherlich immer noch entscheiden was für einen selbst
oder den Anwendungsfall besser wäre bzw. wo die eigenen Vorlieben
währen.
An dieser Stelle nochmal meinen Dank an alle die sich beteiligt haben.
Ovo
Mal ein Beispiel wie sich etwas entwickeln kann:
1990 haben wir mit eine Windows-Entwickling begonnen unter Borland C++
mit einer Klassenbibliothek Namens "StarView". Microsoft hatte damals
nicht mal einen C++ Compiler. Dabei ist Code entstanden der für den
Zweck gut war und bis heute in Teilen unserer Produkte steckt. Danach
ging's ungefähr so weiter:
Borland war irgendwann nicht mehr in der Lage das Projekt zu übersetzen.
Interne Compilerfehler ohne dass der Hersteller darauf reagiert hat.
Wechsel zu Zortech. Die haben auch nicht lange durchgehalten und sind
dann glaube ich von Symantec gekauft worden. Wechsel zu Watcom und
später dann zu Visual C. Mann waren wir froh von vornherein nicht die
C++ StdLib verwendet zu haben und auch keine Templates u.s.w. Zu der
Zeit ist da bei jedem Compiler noch was anderes rausgekommen. Ein
Makrogenerator für Listen u.ä. erfüllt den selben Zweck und ging überall
sofort. Den Quellcode von StarView haben wir dann gekauft und selbst
weitergepflegt. Heute ist StarView (den Namen gibts so nicht mehr) ein
Teil des Unterbaus von OpenOffice.
Später kam dann noch der gcc/g++ unter Linux, Mac und Android dazu sowie
WxWidgets und noch ein paar fremde Libs. Und wiel die Welt so schön ist,
musste für Teile des Codes auch noch ein PHP-, Java- und
JavaScript(V8)-Interface dazu. Da kommt dann Freude auf bei der
Vereinigung der Header, besonders unter Windows. Das Ende vom Lied war
dann eine reine C-Schnittstelle die unseren gesamten objectorientierten
Code in einfache Funktionen mit primitiven Datentypen kapselt, damit das
unter den verschiedensten "Umweltbedingungen" pflegbar bleibt.
Was ich damit nur sagen wollte, es ist nicht immer gut die neusten
Entwicklungen mit zu machen. Eine sinnvolle Beschränkung ist oft besser.
Insbesondere die ganzen neueren C++ Erweiterungen sehe ich jedenfalls
mit große Vorsicht. Will man sie einsetzen muss man sie erst mal lernen.
Das ist ja soweit ganz ok, aber meistens werden die Exoten so selten
benutzt, dass man jedes mal wieder neu nachlesen muss wenn mans
verstehen will. Baue ich die ach so tolle Funktionalität aus ein ein
paar Standardelementen zusammen ist das vielleicht nicht so schön aber
jederzeit nachzuvollziehen ohne sich darüber Gedanke machen zu müssen
was denn der Compiler daraus wieder alles so erzeugt.
Zur Ausgangsfrage. Das reine objektorientierte Programmieren ist wie
wenn ich einer Funktion immer als erstes einen Pointer auf eine Struktur
übergebe und in der Funktion selbst mit den Daten auf diesen Pointer
arbeite. Der Code in der Funktion wird aber wesentlich übersichtlicher
in C++ als in C. Es ist da ein Unterschied ob man schreibt:
a=b+c oder pDaten->a=pDaten->b+pDaten->c
Das spart auch Zeit beim Tippen. Auf die Variante dass a,b und c globale
Daten sind gehe ich hier nicht ein. Sowas kommt bei größeren Projekten
kaum vor.
old man schrieb:> Das reine objektorientierte Programmieren ist wie> wenn ich einer Funktion immer als erstes einen Pointer auf eine Struktur> übergebe und in der Funktion selbst mit den Daten auf diesen Pointer> arbeite.
Du hast 20 Jahre Erfahrung in C++ und reduzierst OO auf so ein ulkiges
Beispiel? Aua. :-(
Fux schrieb:> Du hast 20 Jahre Erfahrung in C++ und reduzierst OO auf so ein ulkiges> Beispiel? Aua. :-(
Es ist ein Beispiel angepasst an die Fragestellung. Nicht mehr und nicht
weniger. Sorry, wenn ich hier nicht anfange wissenschaftliche Vorträge
zu halten. Die üblichen Beispiele kann sich jeder selbst aus den
Internet suchen und was daraus machen oder nicht. Leute die auf Biegen
und Brechen alles dem neusten Hype unterordnen kenne ich zur genüge. Das
sind auch immer die, bei denen ein "Hello Word" aus 10MB und 20
verschiedene Dll's besteht.
Der TE hat hier im Context von µC's gesprochen, und wenn ich C++ auf
Controllern verwende, dann mit Sicherheit ohne C++StdLib und so. Die
uart-Beispiele ziemlich weit oben haben als einzigen Unterschied in etwa
das was ich als Beispiel dargestellt habe. Und wenn einer auf
Controllern sowas wie "new Uart" verzapft, dann kann ich nur sagen:
Schuss nicht gehört!
old man schrieb:> Die uart-Beispiele ziemlich weit oben haben als einzigen Unterschied in> etwa das was ich als Beispiel dargestellt habe.
Eben nicht. Technisch betrachtet ist das in diesen Faellen so, aber
konzeptionell eben nicht. Und um das Konzept geht es, nicht ob der
Pointer links oder rechts vom Methodennamen steht. Bei den obigen
Beispielen geht es in erster Linie um Kapselung.
Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme
mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und
Verwendung von Interfaces klappt das.
Fux schrieb:> Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme> mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und> Verwendung von Interfaces klappt das.
Ne, schon mal ein PHP-Interface geschrieben? Oder ein asterisk-Plugin?
PHP ist im Kern reines C. asterisk auch. Als Interface gibt's nur
C-Funktionen. In dem Interfaceteil selbst kannst du da überhaupt keine
C++ Header einbinden. Umgedreht schon, vorausgesetzt die Authoren dieser
Header haben sich darüber Gedanken gemacht im C++ Umfeld included zu
werden. Aber ganz im Ernst. Entweder du hast schon mal ein
Php-Interface(Plugin) geschrieben und wir Unterhalten uns auf gleicher
Augenhöhe oder du redest nicht über etwas was du nicht kennst.
ich würd ganz gern (ohne arduino-software) OO auf dem AVR machen. Aber
es gibt keinen Beispiel 'hallo-welt'-led-blink code in c++ den ich mal
eben mit avr-g++ compilieren kann. Das läuft um darauf dan aufbauen was
zu proggen ohne vorher mit der toolchain kämpfen zu müssen.
>a couple of months ago I started with AVR and c++. It's rather painful adventure,
but now most of things seems to work
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453&start=all&postdays=0&postorder=asc
wow, klingt ja easy.
_extension_ typedef int __guard __attribute__((mode (_DI_)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
klingt logisch, das brauch ich, dann kann ich auch irgendwie c++ auf avr
machen - easy peasy.
nagut, brauch ich halt ne Menge boilerplate-code denn man halt
copy+paste macht. total häßlich, aber wenns hilft.
Wie haben die arudino-leute eigendlich c++ lauffähig gemacht. und wenn
das so kompliziert ist im setup, wo ist eigendlich der Unterschied
zwischen "richtigem c++ auf avr mit viel boilerplate-code" oder gleich
die "hihihi, du NOOB-Aurdino-software" zu nutzen?
old man schrieb:> Fux schrieb:>> Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme>> mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und>> Verwendung von Interfaces klappt das.>> Ne, schon mal ein PHP-Interface geschrieben? Oder ein asterisk-Plugin?> PHP ist im Kern reines C. asterisk auch. Als Interface gibt's nur> C-Funktionen. In dem Interfaceteil selbst kannst du da überhaupt keine> C++ Header einbinden. Umgedreht schon, vorausgesetzt die Authoren dieser> Header haben sich darüber Gedanken gemacht im C++ Umfeld included zu> werden. Aber ganz im Ernst. Entweder du hast schon mal ein> Php-Interface(Plugin) geschrieben und wir Unterhalten uns auf gleicher> Augenhöhe oder du redest nicht über etwas was du nicht kennst.http://www.php.net/manual/de/language.oop5.php
Und wie schon oben erwähnt ist OO ein Konzept und Mischungen kommen
durch "dynamisches wachsen" vorhandenen Codes vor.
Wenn man von Anfang an das OO Konzept verfolgt gibt es keine
Vermischungen und somit zu keinen Problemen.
Interfaces lassen sich auch objektorientiert programmieren siehe z.B.
SOAP.
cppler schrieb:> http://www.php.net/manual/de/language.oop5.php>> Und wie schon oben erwähnt ist OO ein Konzept und Mischungen kommen> durch "dynamisches wachsen" vorhandenen Codes vor.
Wir reden da aneinander vorbei. Ich meine kein in PHP geschriebenes
Modul sondern eine Extension als .dll oder .so für php. Und da gibst nun
mal nur C und nichts weiter. Ich bin bei meinen Ausführungen nicht auf
die OO im allgemeinen eingegangen und das Konzept dahinter, sondern auf
C/C++ und Controller. Und auf Projekte die so lange laufen, dass sie
auch die übernächste Hype noch überleben. Vorausgesetzt man springt
nicht blind auf jeden Zug auf.
> Wenn man von Anfang an das OO Konzept verfolgt gibt es keine> Vermischungen und somit zu keinen Problemen.
Ach ja. Hast du mal überlegt dass Anfang hier 1990 heiß? Ohne Internet,
ohne TcpIp,COM,Net,SOAP,RPC.......
Da du auch SOAP erwähnst. Hast du dir mal die Frage gestellt wieviel
Overhead in so einer Schnittstelle wie SOAP steckt. In der
Implementierung meine ich. Und wofür? Dafür dass ein AJAX-Request
vielleicht 30Byte JSON-codiert zum Server schickt und als Return auch
nur mit JSON was anfangen kann? Gefühlte 10000 Zeilen Quellcode (incl.
xml) in mindestens 3 verschiedenen Libs die drunter liegen...
Komfort ist nicht alles. Und lesbarer wird es auch nicht zwingend.
Klar findet man hier auch objektorientierte Ansätze in C. Darum ging es
aber nicht. Ich wollte nur die Krux darstellen die man, wenn man größere
Libs in C++ geschrieben hat und jetzt ein Bindig für PHP braucht. Das
heisst: C++ -> C -> PHP -> ...
Die Php-Programmierer finden dann wieder ihre Objekte. Aber die
Zwischenschicht macht eben halt die Rolle Rückwärts.
old man schrieb:> cppler schrieb:>> Wenn man von Anfang an das OO Konzept verfolgt gibt es keine>> Vermischungen und somit zu keinen Problemen.>> Ach ja. Hast du mal überlegt dass Anfang hier 1990 heiß? Ohne Internet,> ohne TcpIp,COM,Net,SOAP,RPC.......>
Da reden wir ebenfalls aneinander vorbei "Anfang" bedeutet bei einem
NEUEN Projekt von Anfang an das OO-Modell umzusetzen.
Und TCP/IP wurde 1983 erstmals vollständig eingesetzt.
RPC gab's schon bei Mainframes und das alles hat nichts mit dem Anfang
eines Projektes zu tun.
> Da du auch SOAP erwähnst. Hast du dir mal die Frage gestellt wieviel> Overhead in so einer Schnittstelle wie SOAP steckt. In der> Implementierung meine ich. Und wofür? Dafür dass ein AJAX-Request> vielleicht 30Byte JSON-codiert zum Server schickt und als Return auch> nur mit JSON was anfangen kann? Gefühlte 10000 Zeilen Quellcode (incl.> xml) in mindestens 3 verschiedenen Libs die drunter liegen...> Komfort ist nicht alles. Und lesbarer wird es auch nicht zwingend.
Da es aber als Objekt implementiert ist kann man es einfach erben und
muß es nicht immer wieder neu kopieren oder schreiben.
Das es Fälle gibt wo etwas keinen Sinn ergibt läßt sich für alle
Programmierparadigmen finden.
Wenn ich in der Lage bin mein Paradigma komplett durchzuziehen habe ich
aber größere Vorteile als wenn ich nun ein propietäres Protokoll selber
entwickeln muß das später zu unflexibel ist um den Anforderungen zu
genügen.
Wenn ich also eine universelle Schnittstelle habe die beliebige Objekte
überträgt, speichert oder umformt habe ich mehr Vorteile als Nachteile.
Bei µCs hat OO ebenfalls Vorteile, bei kleinen Projekten/Controllern
macht es allerdings durchaus Sinn alles Prozedural oder gar in Assembler
zu erledigen.
Das hat aber nichts mit OO zu tun, sondern Notwendigkeiten.
cppler schrieb:> Da reden wir ebenfalls aneinander vorbei "Anfang" bedeutet bei einem> NEUEN Projekt von Anfang an das OO-Modell umzusetzen.> Und TCP/IP wurde 1983 erstmals vollständig eingesetzt.> RPC gab's schon bei Mainframes und das alles hat nichts mit dem Anfang> eines Projektes zu tun.
Ich sprach vom realen Anfang unseres Projektes und nicht von irgendwas
theoretischen. Das gabs Windows 3.0 auf dem Rechner und nix mit TcpIp.
Da musste der Rechner neu gebootet werden wenn ein Pointer im Wald stand
und das größte zusammenhängende Stück Speicher war 64kb groß.
> Wenn ich in der Lage bin mein Paradigma komplett durchzuziehen habe ich> aber größere Vorteile als wenn ich nun ein propietäres Protokoll selber> entwickeln muß das später zu unflexibel ist um den Anforderungen zu> genügen.
laber, laber, laber...
Wenn ich solche Sätze höre wie "das OO-Modell umzusetzen". Das ist wie
bei den Gitarristen die sich den ganzen Tag über Amps und Effekte
ergiessen aber nur bis zu "raising sun" mitgekommen sind.
> Bei µCs hat OO ebenfalls Vorteile, bei kleinen Projekten/Controllern> macht es allerdings durchaus Sinn alles Prozedural oder gar in Assembler> zu erledigen.> Das hat aber nichts mit OO zu tun, sondern Notwendigkeiten.
Auch hier lehrt die Praxis manchmal was anders. Die Architektur von
einem kleinen AVR "mag" es wenn Daten über einen Pointer angesprochen
werden. Das kann C und struct sein oder C++ und Klassen. Der Compiler
erzeugt dabei oft kompakteren Code als mit globalen Variablen. Mit C++
wird das ganze aber deutlich lesbarer. Ob das was dabei rauskommt zu
irgendeiner Definition aus irgendeinem Lehrbuch passt interessiert
wirklich keinen.
Ovo schrieb:> Ich benutze seit Jahren meine UART Funktion und gebe sie auch gerne> anderen die diese einfach benutzen können. Wieso sollte man diese> Funktion nun OO umsetzen?
Um sie in einem Projekt zu verwenden, dass objektorientiert programmiert
wird. Deine Funktion würde Methode genannt und wäre Teil einer Klasse
anstatt Teil eines Moduls.
An der Funktion selbst würde sich kaum etwas ändern.
> x = new senden();> x.schnittstelle(Schnittstelle1);> x.senden("Hallo Welt");
In der Hauptroutine hättest Du soetwas wie:
SCHNITTSTELLE Schnittstelle1 = new Uart (9600, 8, 1, "Com2");
SCHNITTSTELLE Schnittstelle2 = new Usb (foo);
SCHNITTSTELLE Schnittstelle3 = new Wlan (bar);
An die Programmteile die etwas übertragen sollen übergibst Du dann die
entsprechende Schnittstelle. In diesen Teilen brauchst Du dich dann
nicht darum zu kümmern, über welche Schnittstelle die Informationen
gesendet werden, beim programmieren dieser Teile weißt Du das noch nicht
einmal.
Du verwendest dort immer:
MeineSchnittstelle.senden ("Hallo Welt");
Dadurch kannst Du die verwendeten Schnittstellen zentral verwalten und
ändern ohne Rücksicht auf andere Programmteile nehmen zu müssen.
Natürlich geht das auch problemlos mit C. Sprachen, die
objektorientierte Programmierung unterstützen, fördern und unterstützen
eine derartige Vorgehensweise.
Natürlich ist diese Vorgehensweise weniger interessant, wenn das
Programm nie auf eine andere Schnittstelle als die serielle zugreifen
wird. Aber wenn Du Programmteile eines Tages für ein anderes Programm
verwenden willst dann brauchst du nicht den Code auf
"senden(Schnittstelle1,..." durchsuchen um dort eine andere
Schnittstelle einzustellen.
> wo ist genau der Vorteil zu Prozeduralen Programmen
Keiner, Prozeduren bleiben erhalten. (In den meisten OO-Sprachen.)
Die richtige Frage wäre:
Wo ist der Vorteil zur modularen Programmierung.
OOP ein Hype? Für GUIs? Really? _Das_fällt den meisten dazu ein?
kopfkratz
OOP ist ein Paradigma zur SW-Entwicklung. Den meisten hier scheinen
Typsysteme, Polymorphismus usw. da nicht einzufallen - gut, müssen Sie
auch nicht, aber dann diskutiere ich hält nicht mit. Schuster und
Leisten...
OOP ist nicht "besser", OOP ist "anders".
C++ ist eine multiparadigmen-Sprache, deren STL nicht wirklich viel mit
OO zu tun hat, da sie rein auf syntaktischer/prozeduraler
Präprozessorersetzung aufbaut. Wer jetzt schreit: Bounded Polymorphism
mit STL? Bitte erklärts mir.
Und obwohl das hier mikrocontroller.net ist, ist dies hier das PC
unterforum, weshalb Diskussionen über OOP und embedded AFAIK nur bedingt
weiterführen - aber vielleicht habe ich das "PC" falsch verstanden.
OP:
>Somit kommen wir wieder zur Eingangsfrage: Ich habe schon verstanden was>es mit Klassen, Vererbungen, etc. etc. auf sich hat, aber wo ist genau>der Vorteil zu Prozeduralen Programmen die aus Funktionen und Statischen>Elementen aufgebaut sind?
Das mit der Vererbung etcetc scheinst Du nur angeschaut, aber nicht
verstanden zu haben, sonst würdest Du andere Beispiele/Fragen anführen.
Von daher: wenn non-OOP für dich taugt, bleib dabei. "There is no Silver
Bullet"
Tipp zum Googlen: "Cardelli Type Systems"
Viele Grüße
Tobias K. schrieb:> OOP ein Hype? Für GUIs? Really? _Das_fällt den meisten dazu ein?> kopfkratz
Das ist halt ein Forum für Lötkolbediener, die sind schon froh wenn der
µC die LEDs einschaltet, bischen UART-Datengeschubse, hier mal was mit
I2C abgefragt, dort mal was per SPI rübergeschoben, der Rest ist Port
ein/aus Schalterei, da braucht man wirklich kein OOP und wenn dann gibts
das meiste schon fertig als Lib., komplexe Projekte wo OOP seine
Vorteile zeigt sehen anders aus, bei ein paar mickrigen kB RAM macht das
nich viel Sinn und ist eher lächerlich siehe dem Arduinogeraffel.
Wenn sie dann mal was in OOP umsetzen ist das meistens grauenhaft und zu
Recht schrott, das liegt dann aber nicht an OOP/C++ sondern an
mangelndem Verständniss und/oder falschem Einsatzzweck
Schwen Gel schrieb:> Wenn sie dann mal was in OOP umsetzen ist das meistens grauenhaft und zu> Recht schrott, das liegt dann aber nicht an OOP/C++ sondern an> mangelndem Verständniss und/oder falschem Einsatzzweck
So sieht's aus.