Forum: PC-Programmierung OOP - Wie tief sollten Klassen gehen?


von Kevin (Gast)


Lesenswert?

Hallo,

aktuell möchte ich ein kleines Miniprojekt in C# erstellen und einen 
Temperatursensor auslesen - gerne würde ich hierbei auch OOP anwenden.

In wie weit organisiert man alles in Klassen?

Muss ich also eine Klasse "Temperatur" anlegen? (hier könnte man ja 
zwischen Fahrenheit und Celsius unterscheiden?

Außerdem muss ich ja sicher eine Klasse Sensor anlegen. Wie weit würde 
man das ganze noch aufdroeseln?

Vielen Dank,
Kevin

von Fred (Gast)


Lesenswert?

Kevin schrieb:
> (hier könnte man ja
> zwischen Fahrenheit und Celsius unterscheiden?

Brauchst du denn beides?

Nichts ist schlimmer, als Klassenhierarchien "auf Vorrat" zu 
vervollständigen.

von Jan H. (j_hansen)


Lesenswert?

Das kommt auf das Projekt an. Aber prinzipiell hört sich das schon gut 
an. Eine Klasse Temperatur (könnte man auch von einer allgemeineren 
Klasse für Größen mit Einheiten ableiten, ist hier aber wohl zu viel des 
Guten).
Die hat dann z.B. get/set unit und get/set value.

Das Projekt scheint ja klein zu sein, da bringt OOP nicht viel. 
Interessant wird es, wenn du verschiedene Sensoren hast. Wenn du die 
Implementierungen von einer schönen Klasse "Sensor" ableiten kannst, 
dann wird es praktisch. Dazu musst du dir aber gut überlegen, was eine 
generische Sensor-Klasse können soll und was nicht.

von Kevin (Gast)


Lesenswert?

super, vielen Dank für eure Antworten.

Dann bin ich ja schon einmal nicht auf dem Holzweg.


>
> Nichts ist schlimmer, als Klassenhierarchien "auf Vorrat" zu
> vervollständigen.

Ist das wirklich so? Ich dachte gerade für sowas wäre OOP super?!

von Kollege (Gast)


Lesenswert?

Kevin schrieb:
> super, vielen Dank für eure Antworten.
>
> Dann bin ich ja schon einmal nicht auf dem Holzweg.
>
> Nichts ist schlimmer, als Klassenhierarchien "auf Vorrat" zu
> vervollständigen.
>
> Ist das wirklich so? Ich dachte gerade für sowas wäre OOP super?!

Over Engineering geht auch ohne OOP.

"You ain't gonna need it" schon mal gehört?

Flache Hierarchien sind besser denn Vererbung koppelt am stärksten, 
besonders wenn mann nicht nur die Schnittstellen sondern auch die 
Implementierung erbt.

von Mark 99 (Gast)


Lesenswert?

Jan Hansen schrieb:
> Die hat dann z.B. get/set unit und get/set value.

Beeep, beep, beep, Anti-OO Alarm.

Ein gutes Objekt macht seinen internen Zustand nicht von Außen 
erreichbar.

von Fred (Gast)


Lesenswert?

Kevin schrieb:
> Ist das wirklich so? Ich dachte gerade für sowas wäre OOP super?!

Ja, dafür ist OOP super. Sie verleitet dazu, Dinge vorzusehen, die kein 
Mensch braucht.

Beispiel: Du entwickelst eine Software, um Zootiere zu verwalten.

Dann hast du eine Oberklasse "Tier". Dabei fällt dir auf, daß du da 
erstmal Unterklassen "Mensch" und "richtiges Tier" bilden kannst, weil 
Menschen biologisch ja Tiere sind.

Menschen mußt du zwar nicht verwalten, aber so ist es "ordentlicher".

Einzeller hast du zwar im Zoo überall, aber verwalten mußt du die nicht. 
Trotzdem, warum nicht in Ein- und Mehrzeller unterteilen?

Pilze sind zwar neben Pflanzen und Tieren ein eigenes Reich, aber 
manchmal zählt man sie ja eher zu Tieren. Also nochmal Pilze aufnehmen.

All diese Klassen, die du für deine Anwendung nicht brauchst, kannst du 
alle noch x-fach weiter unterteilen. Ist ja richtiger so.

Die werden zwar alle nie instantiiert werden, aber es ist doch schön, 
die Welt korrekt abgebildet zu haben.


Erfahrene OOP-Entwickler machen solche Fehler natürlich nicht. Anfängern 
passiert das aber ständig.

Deshalb nochamal: unterscheidet die Anwendung wirklich zwischen 
verschiedenen Temperaturskalen, oder ist das nur, weils den inneren 
Linnaeus befriedigt?

von Jan H. (j_hansen)


Lesenswert?

Mark 99 schrieb:
> Beeep, beep, beep, Anti-OO Alarm.
>
> Ein gutes Objekt macht seinen internen Zustand nicht von Außen
> erreichbar.

Ich denke du hast das mit dem internen Zustand falsch verstanden. Wenn 
mir das Objekt weder Temperatur noch Einheit verrät, dann ist es nutzlos 
;) Man muss die Getter/Setter ja nicht direkt auf die internen Variablen 
setzen. Zusatzlogik (Prüfung ob neue Einheit gültig ist, automatische 
Umrechnung der Temperatur, nicht weniger als absoluter Nullpunkt usw...) 
kann man ja vorsehen, oder auch später bei Bedarf dazuprogrammieren. 
Solange das alles über Getter/Setter läuft ist das kein Problem und auch 
richtig gekapselt. Und kann problemlos erweitert werden.

von Kevin (Gast)


Lesenswert?

> Deshalb nochamal: unterscheidet die Anwendung wirklich zwischen
> verschiedenen Temperaturskalen, oder ist das nur, weils den inneren
> Linnaeus befriedigt?

Jetzt leuchtet mir mehr ein, worauf die Aussage bezogen war. - Vielen 
Dank ;-)

Nein, Celsius reicht eigentlich vollkommen aus.

von Jan H. (j_hansen)


Lesenswert?

Kevin schrieb:
> Nein, Celsius reicht eigentlich vollkommen aus.

Was aber nicht heißt, dass es nicht trotzdem schlau wäre ein Objekt 
daraus zu machen. Vererbung wird zwar meist als die primäre Nutzung von 
OOP gelehrt, in der Realität ist das aber anders.

Gerade Kapselung ist sehr nett. Wenn du später einmal eine Überprüfung 
des Wertebereichs hinzufügen möchtest, dann geht das total einfach wenn 
die Temperatur ein Objekt ist.

Wenn du die Temperatur einfach als Variable "herumliegen" hast, dann 
musst du die Logik überall vorsehen wo der Wert gesetzt wird, oder alle 
diese Stellen auf eine Validierungsfunktion umbiegen.

Das hängt dann auch stark vom Projekt selbst ab was man als Objekt 
modelliert und was nicht.

von Kevin (Gast)


Lesenswert?

Jan Hansen schrieb:
> Kevin schrieb:
>> Nein, Celsius reicht eigentlich vollkommen aus.
>
> Was aber nicht heißt, dass es nicht trotzdem schlau wäre ein Objekt
> daraus zu machen. Vererbung wird zwar meist als die primäre Nutzung von
> OOP gelehrt, in der Realität ist das aber anders.
>
> Gerade Kapselung ist sehr nett. Wenn du später einmal eine Überprüfung
> des Wertebereichs hinzufügen möchtest, dann geht das total einfach wenn
> die Temperatur ein Objekt ist.
>
> Wenn du die Temperatur einfach als Variable "herumliegen" hast, dann
> musst du die Logik überall vorsehen wo der Wert gesetzt wird, oder alle
> diese Stellen auf eine Validierungsfunktion umbiegen.
>
> Das hängt dann auch stark vom Projekt selbst ab was man als Objekt
> modelliert und was nicht.

Genau das war ja eigentlich meine Eingangsfrage. In wie weit macht es 
Sinn die Klassen aufzuschlüsseln?

Kann man pauschal einfach sagen, dass man sich auf jeden Fall nach oben 
immer eine Vererbungsklasse Luft lassen sollte? - wenn man das so sagt^^

von greg (Gast)


Lesenswert?

Vererbung ist gerade DAS Element von OOP, was man nur sehr vorsichtig 
einsetzen sollte. Wenn man große Vererbungshierarchien hat, sinkt die 
Übersicht enorm, und es wird immer schwerer herauszufinden, was das 
Programm da tatächlich eigentlich macht. Und jede Änderung an einer 
Klasse in der Hierarchie hat das Potential, Fehler zu verursachen. Nicht 
umsonst sagt man, dass Komposition der Vererbung vorzuziehen ist. Oft 
ist es auch besser, ein paar Zeilen Code zu duplizieren, statt Vererbung 
einzusetzen.

Komplexität ist i.A. das größte Problem bei Softwareentwürfen, daher 
sollte man die Komplexität nicht noch künstlich erhöhen.

von Jan H. (j_hansen)


Lesenswert?

Kevin schrieb:
> Genau das war ja eigentlich meine Eingangsfrage. In wie weit macht es
> Sinn die Klassen aufzuschlüsseln?

Klein und fein ist schon in Ordnung. Nicht zu viel in eine Klasse 
packen.

> Kann man pauschal einfach sagen, dass man sich auf jeden Fall nach oben
> immer eine Vererbungsklasse Luft lassen sollte? - wenn man das so sagt^^

Das ist ein anderes Thema. Nein, ich würde da keine "Luft lassen" 
(jemand weiter oben hat schon YAGNI genannt). Wenn du nur einen Sensor 
hast und kein anderer dazukommt, dann genügt eine Klasse und du kannst 
dir die Vererbung schenken. Wenn irgendwann einmal doch ein anderer 
Sensortyp dazukommen würde, dann kannst du noch immer eine Superklasse 
extrahieren und die jetzige davon ableiten. Da musst du nicht "auf 
Vorrat" arbeiten. Keep it simple.

von Kollege (Gast)


Lesenswert?

Jan Hansen schrieb:
> Ich denke du hast das mit dem internen Zustand falsch verstanden. Wenn
> mir das Objekt weder Temperatur noch Einheit verrät, dann ist es nutzlos
> ;) Man muss die Getter/Setter ja nicht direkt auf die internen Variablen
> setzen. Zusatzlogik (Prüfung ob neue Einheit gültig ist, automatische
> Umrechnung der Temperatur, nicht weniger als absoluter Nullpunkt usw...)
> kann man ja vorsehen, oder auch später bei Bedarf dazuprogrammieren.
> Solange das alles über Getter/Setter läuft ist das kein Problem und auch
> richtig gekapselt. Und kann problemlos erweitert werden.

Für alles Setter zu haben widerspricht der OO Natur, das macht man bei 
Datenstrukturen, in Java wären das die JavaBeans ;)

Fowler nennt das "Anemic Domain Modell", führt dazu dass die Logik 
woanders  implementiert werden als dort wo doie eigentlichen Daten, so 
wie man es vom Prozeduralen Ansatz her kennt.

Ansosnten gibt es einen grossen Unterschied zwischen "Encapsulation" und 
"Information Hiding", wird oft durcheinander gewürfelt.
Wenn man mit einem Getter ein mutable Objekt zurückgibt, war es das mit 
der Kapselung..

von MaWin (Gast)


Lesenswert?

Kevin schrieb:
> In wie weit organisiert man alles in Klassen?

Gar nicht.

Da du nur eine Instanz von Sensor und nur eine Instanz von Temperatur 
haben wirst, sind Klassen absolut überflüssig.
Du wirst keinerlei objektorientierte Methode benötigen, wie Vererbung, 
Polymorphismus, und keine Objekte anlegen und verwerfen auf dem uC.

Ein Programm ist dann optimal, wenn sich nichts mehr weglassen lässt, 
ohne daß dann die Funktion nicht mehr erfüllt wäre, unter weglassen 
versteht man die Maschineninstruktionen während der Abarbeitung, nicht 
die Anzahl der Kommentare.

Zwar muss nicht jede Spielerei optimal werden, aber vorsätzlich den 
entgegengesetzen Weg einzuschlagen ist schon sehr realitätsverweigernd.

von Oliver (Gast)


Lesenswert?

MaWin schrieb:
> Ein Programm ist dann optimal, wenn sich nichts mehr weglassen lässt,
> ohne daß dann die Funktion nicht mehr erfüllt wäre, unter weglassen
> versteht man die Maschineninstruktionen während der Abarbeitung, nicht
> die Anzahl der Kommentare.

Na ja, das war vielleicht zu Zeiten der Lochkarten mal so.

In dem vorliegenden Fall ist ein Programm dann optimal, wenn es mit 
möglichst wenig zusätzlichem Dokuemntationsaufwand leicht verständlich 
und testbar formuliert ist.

Und ja, dabei helfen sinnvoll gestaltete Klassen ungemein.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

> einmal doch ein anderer Sensortyp dazukommen würde, dann kannst du
> noch immer eine Superklasse extrahieren und die jetzige davon ableiten.

Das sehe ich eigentlich als den Hauptvorteil einer objekt basierten 
Herangehensweise an: man kann auch im Nachhinein oft noch neue Klassen 
einziehen, wenn sich die Forderungen im Programm verändern, ohne dass 
gleich alles zusammenbricht.

Und ja. Ich hab in meinen OOP Anfängen auch genau den Fehler gemacht, 
viel zu früh viel zu viel 'Flexibilität' in das Klassendesign auf Vorrat 
einzubauen. Das Ergbnis war eine undurchschaubare Hierarchie, die zwar 
im Prinzip alle möglichen Stückerl gespielt hätte ... wenn sie denn je 
irgendjemand gebraucht hätte. Nach ein paar Jahren ist dieser Teil des 
Programms (es ging um Operatoren in einem CAD Programm und wie 
Mausmessages in diesem Konglomerat ihre Ergüsse an dieser Operatoren 
weiter geben, die dann wieder über Zeichenklassen den Cursor bzw. 
Hilfsgeometrie steuern) dann rausgeflogen und mit einem viel einfacheren 
Mechanismus ersetzt worden, der dann auch wesentlich fehlerunanfälliger 
war.


Klassenhierarchien muss man immer im Kontext der konkreten 
Aufgabenstellung sehen. Was in der einen Aufgabenstellung sinnvoll ist, 
muss in einer anderen Aufgabenstellung keineswegs sinnvoll sein

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

Oliver schrieb:
> In dem vorliegenden Fall ist ein Programm dann optimal

Nein, optimal ist definiert, besuche eine Informatik-Vorlesung.

Du meinst vielleicht hübsch.

Aber hübsch liegt immer im Auge des Betrachters.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Kevin schrieb:
> Muss ich also eine Klasse "Temperatur" anlegen? (hier könnte man ja
> zwischen Fahrenheit und Celsius unterscheiden?

Wieso sollte man das tun? Deine Klasse (besser wäre sogar ein Interface) 
Temperatur kapselt einfach einen Wert (z.B. double, int o.ä.) und stellt 
einen Typ dar (am besten nicht veränderbar).
Außerdem hat sie einen Getter, welcher den Wert in der normierten 
Einheit Kelvin zurückliefert. Eventuell hat sie noch Operatoren um 
Temperaturen zu addieren/subtrahieren/serialisieren o.ä.

Wenn du nun aus irgendwelche Gründen in der Präsentationsschicht die 
Ausgabe einer Temperatur in °Celsius oder °Fahrenheit benötigst dann 
erstellst du dir einfach eine Formatierfunktion
1
formatTemp(Temperatur t, Einheit e, int nachkommastellen);
Diese kann dann jedwede Temperatur in den gewünschten Ausgabewert 
umwandeln.

Und dann ist es auch egal ob es genau EINE Temperatur Implementierung 
gibt, oder eine SensorXYZTemperatur welche vielleicht immer live den 
Wert abfragt wenn der getter aufgerufen wird... oder oder ...

Das muss man aber nicht zu dem Zeitpunkt entscheiden wo du die 
Designentscheidung triffst "mein System hat den Typ Temperatur mit den 
Eigenschaften....".

von ah8 (Gast)


Lesenswert?

Kevin schrieb:

> In wie weit organisiert man alles in Klassen?

Bjarne Stroustrup widmet  gleich einen ganze Teil seines Buches ISBN 
3-8273-1660-X (Abschnitt IV: Design Aspekte mit drei Abschnitten und 
insgesamt 22 Kapiteln) dieser Frage. Ist zwar für C++, dürfte aber auf 
C# übertragbar sein.

> Muss ich also eine Klasse "Temperatur" anlegen? (hier könnte man ja
> zwischen Fahrenheit und Celsius unterscheiden?

In http://www.boost.org/ gibt es eine Unit-Library, die das Abbilden von 
Einheiten ermöglicht. Ist sehr interessant, allerdings auch ein 
ziemliches Monster und alles andere als einfach.

von Georg (Gast)


Lesenswert?

Läubi .. schrieb:
> Deine Klasse (besser wäre sogar ein Interface)
> Temperatur kapselt einfach einen Wert (z.B. double, int o.ä.) und stellt
> einen Typ dar (am besten nicht veränderbar)

Ob mit oder ohne OO, verschiedene Temperaturen mitzuführen ist ohnehin 
der völlig falsche Weg. Beispiel aus der CNC-Technik: die Steuerung 
arbeitet grundsätzlich intern mit einer einzigen Masseinheit, z.B. 
1/1000 mm. Inch kann man am Bildschirm sehen, wenn man denn will, oder 
als Bearbeitungsprogramm einlesen, die Maschine weiss nichts davon. 
Würde man die Positionieralgorithmen für verschiedene Masseinheiten 
auslegen käme man in Teufels Küche, was Fehler angeht, und der Aufwand 
ist auch völlig unnötig.

Eine Temperatur ist eine Temperatur ist eine Temperatur und sollte vom 
absoluten Nullpunkt bis zu einer unereichbaren Obergrenze den 
physikalischen Wert mit ausreichender Auflösung darstellen können, das 
ist die primäre Designentscheidung. Ob sie in Kelvin, Celsius oder 
Fahrenheit ein- oder ausgegeben wird ist eine Frage des User Interface 
und nicht des Reglers.

Georg

von MaWin (Gast)


Lesenswert?

Georg schrieb:
> Würde man die Positionieralgorithmen für verschiedene Masseinheiten
> auslegen käme man in Teufels Küche, was Fehler angeht

Das ist so nicht richtig.

Wenn das System inch als Koordinaten bekommt, und inch ausgeben soll, 
treten wenn intern mit inch gerechnet wird keine Rundungsfehler auf, bei 
mm schon.

Daher kann es sinnvoll sein, das zugrundliegende System umzuschalten, 
machen beispielsweise manche Leiterplattenentwurfsprogramme so.

Bei CNC gibt es allerdings eine physikalische Auflösung der Achsen, 
damit sind Rundungsfehler beim Abbilden auf Positionen nicht zu 
vermeiden und es spricht nichts dagegen, mit denen zu rechnen.

Wenn man aber Schrittmotoren mit 64 Schritten pro Millimeter hat, ist es 
blöd, erst die eingegebenen Koordinaten von inch in cm, und dann von cm 
in Schritte umzurechnen, das ergibt bei Schrägen plötzlich 
Streifenmuster an denen die Abbildung auf den nächsten Wert rundet, also 
von abrunden auf aufrunden springt.

von Jan H. (j_hansen)


Lesenswert?

Kollege schrieb:

> Für alles Setter zu haben widerspricht der OO Natur, das macht man bei
> Datenstrukturen, in Java wären das die JavaBeans ;)

Gerade so ein einfaches Temperatur-Objekt ist doch ein perfektes 
Beispiel für ein JavaBean ;)

> Fowler nennt das "Anemic Domain Modell", führt dazu dass die Logik
> woanders  implementiert werden als dort wo doie eigentlichen Daten, so
> wie man es vom Prozeduralen Ansatz her kennt.

Ist ja grundsätzlich nicht schlecht. Und welche Logik möchtest du denn 
bei einem simplen Temperatur-Objekt implementieren? Und warum kann man 
keine Logik implementieren wenn man Getter/Setter verwendet?

> Ansosnten gibt es einen grossen Unterschied zwischen "Encapsulation" und
> "Information Hiding", wird oft durcheinander gewürfelt.
> Wenn man mit einem Getter ein mutable Objekt zurückgibt, war es das mit
> der Kapselung..

Nein, wenn man aus dem internen Zustand ein neues mutable Objekt erzeugt 
und das zurückgibt, dann ist das kein Problem.

von ah8 (Gast)


Lesenswert?

Georg schrieb:
> Würde man die Positionieralgorithmen für verschiedene Masseinheiten
> auslegen käme man in Teufels Küche, was Fehler angeht, und der Aufwand
> ist auch völlig unnötig.

Das Mitführen von Einheiten ist keinesfalls unsinnig, selbst wenn ich 
nur eine Einheit pro Größe im System verwende. Es steht ja nirgends in 
Stein gemeißelt, dass das immer so bleiben muss. Die oben zitierte 
http://www.boost.org/ -Library beweist auch, dass das grundsätzlich 
möglich ist, selbst ohne Laufzeit-Overhead.

> Eine Temperatur ist eine Temperatur ist eine Temperatur ...

Das hatten sich die Programmierer einer gewissen Mars-Sonde wohl auch 
einst gedacht. Dumm nur, dass eine Temperatur – bzw. in diesem Fall war 
es wohl eine Länge – in Amerika eben nicht gleich einer Temperatur in 
Europa ist. Ergebnis: Totalverlust von hunderten Millionen Dollar. Wenn 
das nicht Teufels Küche ist ...

von Kollege (Gast)


Lesenswert?

Jan Hansen schrieb:
> Gerade so ein einfaches Temperatur-Objekt ist doch ein perfektes
> Beispiel für ein JavaBean ;)

Naja, so gesehen ist das ein ganz mieses Beispiel für Obekt als auch 
Datenstruktur ;)
float/double oder gar int passen da viel besser..

Jan Hansen schrieb:
> Ist ja grundsätzlich nicht schlecht. Und welche Logik möchtest du denn
> bei einem simplen Temperatur-Objekt implementieren? Und warum kann man
> keine Logik implementieren wenn man Getter/Setter verwendet?

"Nicht schlecht" sowieso, aber nicht OO!

Schon mal eine JavaBean mit Logik gesehen?
(Validierung zählt nicht)
Schon mal eine JavaBean gesehen die die per Repository/DAO die DB 
abfragt?
"Das darf man nicht.." heisst es dann nicht ohne Grund, echte Objekte 
dürften das.

http://www.martinfowler.com/bliki/AnemicDomainModel.html

Datenstrukturen wie JavaBeans leben eben davon, dass sie weder Kapselung 
noch Information Hiding bieten, sind eben nur Datenstrukturen, oft als 
DTO.

von Georg (Gast)


Lesenswert?

MaWin schrieb:
> Wenn das System inch als Koordinaten bekommt, und inch ausgeben soll,
> treten wenn intern mit inch gerechnet wird keine Rundungsfehler auf, bei
> mm schon.

Das war vielleicht mal richtig. Rundungsfehler sind aber irrelevant, 
wenn die rechnerische Auflösung deutlich höher ist als die mechanische - 
ich habe vor 25 Jahren 32bit Integer verwendet mit der Einheit 1µ, das 
hat Jahrzehnte ausgereicht, da die angeschlossenen Messmaschinen weniger 
als 4m gemessen haben und nicht genauer als 1µ positioniert, allerdings 
gibt es in Wirklichkeit schon Maschinen mit mehr als 4m und Messsysteme 
besser als 1µ. Macht heute aber nix mehr, da 64 bit kein Problem mehr 
ist, also kann man Nanometer auflösen und die Maschine kann so gross wie 
die Erde sein. Wenn ich mich nicht verrechnet habe, aber in jedem Fall 
langt es dicke und Runden ist kein Problem.

Georg

MaWin schrieb:
> Daher kann es sinnvoll sein, das zugrundliegende System umzuschalten,
> machen beispielsweise manche Leiterplattenentwurfsprogramme so.

Meines nicht. CadStar löst 10nm auf, und mir ist noch kein Teil 
begegnet, bei dem Rundungsfehler eine Rolle gespielt hätten.

Georg

von Oliver S. (oliverso)


Lesenswert?

MaWin schrieb:
> Oliver schrieb:
> Nein, optimal ist definiert, besuche eine Informatik-Vorlesung.

Ja na, theoretisch optimal ist in den allermeisten Fällen praktisch 
unbrauchbar.

Oliver

von (prx) A. K. (prx)


Lesenswert?

Oliver S. schrieb:
>> Nein, optimal ist definiert, besuche eine Informatik-Vorlesung.
>
> Ja na, theoretisch optimal ist in den allermeisten Fällen praktisch
> unbrauchbar.

Und genau das lernt man in besagter Informatik-Vorlesung. ;-)

von Jan H. (j_hansen)


Lesenswert?

Kollege schrieb:

> Naja, so gesehen ist das ein ganz mieses Beispiel für Obekt als auch
> Datenstruktur ;)
> float/double oder gar int passen da viel besser..

Es geht aber um OO. Ja, ein primitiver Zahlentyp kann auch sinnvoll 
sein, aber darum geht es hier nicht.

> "Nicht schlecht" sowieso, aber nicht OO!

Also für mich eindeutig schon OO. Warum denn nicht?

> Schon mal eine JavaBean mit Logik gesehen?
> (Validierung zählt nicht)

Ja, Validierung ist auch Logik. Außerdem habe ich nicht mit den 
JavaBeans angefangen, dass die per Definition eingeschränkt sind hat 
nichts mit dem Thema zu tun.

> "Das darf man nicht.." heisst es dann nicht ohne Grund, echte Objekte
> dürften das.

Reines Definitionsproblem. Und natürlich sind auch JavaBeans "echte" 
Objekte.

von MaWin (Gast)


Lesenswert?

Oliver S. schrieb:
> Ja na, theoretisch optimal ist in den allermeisten Fällen praktisch
> unbrauchbar.

Du meinst, praktisch kannst du es nicht und versuchst dich rauszureden.
Davon gibt es tausende.

von Oliver S. (oliverso)


Lesenswert?

Ne, es gibt tausende davon, die übersehen, daß ein optimales Programm 
als allererstes einmal fehlerfrei sein muß. Nicht optimal, aber 
fehlerfrei ist praktisch erheblich besser als gedacht optimal, mit 
Absturz der Ariane als Folge...

O.iver

von MaWin (Gast)


Lesenswert?

Oliver S. schrieb:
> daß ein optimales Programm als allererstes einmal fehlerfrei sein muß.

Der Nachweis ist entschieden einfacher, wenn nur die tatsächlich real 
notwendigen Anweisungen programmiert werden.

>, mit Absturz der Ariane als Folge...

Scheiss Kapselung. Das SRI, das bei Ariane 4 funktionierte, wurde 
ungeprüft übernommen, kam aber mit den anderen Daten intern nicht 
zurecht.

http://m.focus.de/digital/computer/chip-exklusiv/tid-14183/computer-fehler-die-groessten-software-desaster_aid_396628.html

von Moby (Gast)


Lesenswert?

greg schrieb:
> Komplexität ist i.A. das größte Problem bei Softwareentwürfen, daher
> sollte man die Komplexität nicht noch künstlich erhöhen.

Das tut man aber, mit jeder neuen Hochsprache, jeder neuen Library, 
immer neuen Erfindungen, Verfeinerungen und Konstrukten der OOP. Was von 
der Intension her den Softwareentwurf vereinfachen sollte verkompliziert 
ihn letztlich nur.

Kevin schrieb:
> ein kleines Miniprojekt in C#

ist besser in wenigen Codezeilen erstellt die genau das tun was nötig 
ist!
Und wenn wir hier nicht just in der Rubrik PC-Programmierung wären würde 
ich sagen gleich in pure ASM.

von Oliver (Gast)


Lesenswert?

Moby schrieb:
> würde
> ich sagen gleich in pure ASM.

Endlich...
Da habe ich schon seit gefühlten 300 Beiträgen drauf gewartet.

Oliver

von PittyJ (Gast)


Lesenswert?

Hier auch mal mein Senf dazu.

Gerade bei OOP ist viel Erfahrung nötig. Jahrelanges 'Spielen' ist da 
angesagt. Dann bekommt man mit, wo es notwendig ist und wo man es 
einfach beläst.
Mach am besten 2 Versionen. Ein mit viel und eine mit wenig OOP. Und 
dann vergleiche mal die Vor- und Nachteile.
Bei einem anderen programm sieht das dann wieder ganz anders aus.


Zu den Einheiten. Ich mußte lange auch mit vielen physikalischen Größen 
umgehen. Da habe ich mir angewöhnt, immer alles in SI-Einheiten 
abzuspeichern. Da gab es dann nie die Frage, ob noch eine Kilo oder 
micro davor gehört. Umgerechnet wurde nur bei Benutzer Ein/Ausgabe. 
Programmintern war alles pure Meter.

von Moby (Gast)


Lesenswert?

PittyJ schrieb:
> Gerade bei OOP ist viel Erfahrung nötig. Jahrelanges 'Spielen' ist da
> angesagt.

Und genau deshalb ist OOP auch nicht der Weisheit letzter Schluß...

Oliver schrieb:
> Endlich...
> Da habe ich schon seit gefühlten 300 Beiträgen drauf gewartet.

Kann man nicht oft genug sagen.

von Karl H. (kbuchegg)


Lesenswert?

PittyJ schrieb:

> Mach am besten 2 Versionen. Ein mit viel und eine mit wenig OOP. Und
> dann vergleiche mal die Vor- und Nachteile.

Bei so einem Micky Mouse Projekt kann OOP seine Vorteile doch gar nicht 
ausspielen.
OOP kommt dann sinnvoll ins Spiel, wennn die Projektgrößen dergestalt 
sind, dass sie von den Team-Mitgliedern Disziplin erfordern. In 
klassischen prozeduralen Systemen (wie C) vertraut man darauf, dass die 
Programmierer diese Disziplin haben, was oft genug in die Hose geht. In 
OOP Sprachen (wie C++) hat man den Entwicklern Möglichkeiten in die Hand 
gegeben, diese Disziplin einzufordern bzw. das System so aufzubauen, 
dass es schwierig ist, am Gesamtkonzept vorbeizuprogrammieren und es 
leicht ist, es in der Funktionalität zu erweitern.

Ja, bei kleinen Aufgabenstellungen sieht ein C++ Programm daher erst mal 
völlig überkandidelt aus. Das liegt daran, dass im Vergleich zu rein 
prozeduralen Ansätzen der Verwaltungsoverhead im Programmtext relativ 
hoch ist. Aber das verliert sich mit wachsenden Projektgrößen.

> Gerade bei OOP ist viel Erfahrung nötig.
Ein gewisses Mass an 'Beamtenmentalität' ist da sehr hilfreich. Die 
meisten vermurksten OOP Systeme, die ich bisher gesehen habe, drehten 
sich praktisch immer um die Frage "Welche Klasse ist wofür zuständig", 
bzw. eigentlich um das ignorieren dieser Fragestellung. Da wird dann auf 
Teufel komm raus mit Gettern/Settern gearbeitet und Funktionalität 
ausserhalb der zuständigen Klassen implementiert, die eigentlich ganz 
klar in die Klasse rein gehören würde.

: Bearbeitet durch User
von Kollege (Gast)


Lesenswert?

Jan Hansen schrieb:
> Es geht aber um OO. Ja, ein primitiver Zahlentyp kann auch sinnvoll
> sein, aber darum geht es hier nicht.

Dann sind JavaBeans so ganz falsch, den JavaBeans sind eben nicht OO, 
steht schon in meinem letyzten Post warum und wieso, inkl. Link zur 
einer ausführlichen Erklärung.

Jan Hansen schrieb:
> Also für mich eindeutig schon OO. Warum denn nicht?

Hab ich doch eigentlich schon erklärt.

Jan Hansen schrieb:
> Reines Definitionsproblem. Und natürlich sind auch JavaBeans "echte"
> Objekte.

Eben nicht, aber auch das hatte ich schon erklärt.

von Andreas L. (andi84)


Lesenswert?

auf die Gefahr hin, dass ich da nur noch in kaltem Kaffe rühre und alle 
fragen geklärt sind:

Das schöne an OOP ist, es gibt so viele möglichkeiten das zum 
implementieren, wobei flache hierachien meist sinnvoller sind.
Da OOP-Tutorials meist die Konzepte vermitteln wollen, haben die oft 
irrsinnige Abstraktionstiefen.
Oft macht es mehr sinn helperfunktionen einfach static in einer 
basisklasse unterzubringen, als noch eine noch vererbung mehr einzubaun.

Als gute Grundlage zu den DOs und DONTs kann man sich mal die Coding 
guidelines des Qt-Projekts antun,
die sind nicht zu umfangreich, geben aber ein paar schöne Beispiele, was 
sinnvoll ist, was weniger und warum welche Probleme in Qt wie gelöst 
wurden.

Zurück zum Thema:
Wenn ich davon ausginge, dass es mal mehr als ein sensor und typ werden 
könnten und dass ich vllt auch mal mehrere gleichzeitig haben will, 
beides ist ja realistisch möglich, wäre mein konzept wohl wie folgt

Eine Baisklasse
class tempSensor

 public
  getValue(unit);
  getUpdateRate() const;
  setUpdateRate(int);
  getType() const;

sowie
  static convertUnit(value, fromUnit, toUnit);

convertUnit kann temperaturen von einheit a in einheit b umrechnen,
Dazu gibts dann eine Enum der gewünschten Temperaturskalen (Kelvin, 
Celsius, Fahrenheit).

dem getter für die temperatur wird als standardwert für die einheit jene 
zugewiesen, die ich primär nutzen will.

Ja, das könnte man als Klasse "temperatur" kapseln, halte ich aber nicht 
für nötig, weil YAGNI halt.

Die Sensorklasse wird dann für jeden sensortyp abgeleitet, wenn ich 
generische schnittstellen wie I2C oder sowas habe, die mehrere sensoren 
nutzen könnten, wird das gekapselt. Der Konstruktor bekommt die nötigen 
argumente um den sensor auszuwählen. Fertig die laube.
Jetzt kann man sich noch überlegen, ob die sensorklasse noch in der lage 
sein soll, den sensor im hintergrund zu lesen oder whatever.

Klingt jetzt vllt nicht wie die hohe kunst der oop, halte ich aber für 
angemessene abwägung zwischen struktur und simplicity.
Durch die Abstraktion des Temperatursensors als basisklasse kann es 
meinem restlichen code wurst sein, was da später dran hängt.
Durch die static convertUnit kann ich temperaturen jederzeit in andere 
einheiten umrechnen. Das Tracking der Temperatureinheit muss dann zwar 
der den wert jeweils nutzende code machen, aber die umschaltung zwischen 
den einheiten ist ja auch eher selten.

So ist es zum beispiel bei einer aufgezeichneten temperaturkurve nicht 
sinnvoll, pro wert die einheit zu speichern, vielmehr werden wohl alle 
messwerte die gleiche haben. Das ggf. nötige umrechnen kann der 
anzeigende code machen mit tempSensor::convertUnit, wenns sein muss.

von W.S. (Gast)


Lesenswert?

Karl Heinz schrieb:
> OOP kommt dann sinnvoll ins Spiel, wennn die Projektgrößen dergestalt
> sind, dass sie von den Team-Mitgliedern Disziplin erfordern.

Ach Karlheinz, DAS ist es eigentlich nicht.

Objektorientierte Programmierung hat genau dort ihren Sinn, wo mehrere 
äußerlich gleichartig zu behandelnde, aber innerlich unterschiedliche 
Objekte existieren. Ein typisches beispiel sind die diversen Kringel auf 
einer grafischen Benutzeroberfläche.

Aber all das ist hier nicht der Fall. Der TO will einen Temperaursensor 
auslesen und (vermutlich) dessen Temperaturwert auf irgend so einer 
grafischen Oberfläche anzeigen. Wenn er dazu ne grafische 
Klassenbibliothek benutzt, so hat es dort ganz gewiß genug passende 
Objekttypen, die er benutzen kann.

Aber ne Klasse "Sensor" und ne klasse "Temperatur" ist schlichtweg 
albern und unsachgemäß. Allein schon aus der logischen Erwägung heraus, 
daß unterschiedliche Sensoren ja unterschiedliche Ergebnistypen liefern: 
ein Thermometer liefert was anderes als ne Waage odeer ein Zollstock. 
Die Ergebnisse sind nicht kommensurabel, also kann es keine 
zusammenfassende Klasse für sowas geben.

Das Gegenteil liefert der Gedanke an eine Klasse "Temperatur". Hier ist 
es nicht die inkommensurable vielfalt, sondern die öde Einfalt: 
Temperaturen haben kein eigenes Innenleben, so daß man aus verschiedenen 
Temperaturen eine Klasse bilden könnte. Das ist also auch völliger 
Murks.

Oh ihr grandiosen Programmierer, lernt vor dem In_Die_Tasten_Hauen doch 
um himmelswillen wenigstens ein klein wenig Logik. Das würde die Welt 
verbessern.

W.S.

von Markus (Gast)


Lesenswert?

W.S. schrieb:
> Das Gegenteil liefert der Gedanke an eine Klasse "Temperatur". Hier ist
> es nicht die inkommensurable vielfalt, sondern die öde Einfalt:
> Temperaturen haben kein eigenes Innenleben, so daß man aus verschiedenen
> Temperaturen eine Klasse bilden könnte. Das ist also auch völliger
> Murks.

Die Temperatur als Klasse zu modellieren ist sogar sehr sinnvoll. Eine 
Temperatur hat einen (im Vergleich zu dem skalaren Typ int) 
eingeschränkten Wertebereich. Wenn Du keinen eigenen Typ für die 
Temperatur hast, müsstest Du korrekterweise bei jeder Zuweisung einen 
Range-Check machen. Weiter macht es überaus Sinn, dass die 
Temperaturklasse verschiedene Konvertierungen bietet, z.B. nach String, 
...

Clean-Code Koriphäen wie Robert C. Martin empfehlen dringend für Domains 
wie Währung, Geschwindigkeit, Temperatur, ... grundsätzlich eigene 
Klassen zu verwenden. Das macht den Code erstens leserlicher und 
zweitens leichter wartbar. Und das ist nicht nur bei großen Projekten 
sinnvoll.

Aus eigener Erfahrung kann ich nur ins Feld führen, dass man irgendwann 
mal klein beginnt (kleines Programm), sich die Dinge aber 
unerwarteterweise plötzlich verselbständigen und schnell wachsen. Und 
dann steht man vor einem Chaos-Haufen. :-(

Grüße
Markus

von Georg (Gast)


Lesenswert?

Hallo,

zusammen mit der "Erfindung" von OO kam eine Programmiersprache heraus, 
deren Name mir entfallen ist (irgendwas mit A), die von extremen 
Verfechtern der OO-Prinzipien konzipiert wurde. Die Sprache kannte keine 
Zahlen, sogar ein Bit war eine Klasse - mit Setter, um es wahr oder 
falsch zu setzen, getter, um es abzufragen, constructor, destructor 
usw., und Methoden für and, or, xor...

Für mich kam das nicht in Frage, weil man sich den Aufwand im 
Embedded-Bereich mit den damaligen Prozessoren der Z80-Klasse überhaupt 
nicht leisten konnte. Ausserdem sehe ich das als fehlgeleitete 
Ideologie, ich schreibe zwar seit 20 Jahren OO-Programme, aber ich 
erwarte trotzdem, dass man 2 Ganzzahlen noch normal addieren kann.

Georg

von Karl H. (kbuchegg)


Lesenswert?

W.S. schrieb:
> Karl Heinz schrieb:
>> OOP kommt dann sinnvoll ins Spiel, wennn die Projektgrößen dergestalt
>> sind, dass sie von den Team-Mitgliedern Disziplin erfordern.
>
> Ach Karlheinz, DAS ist es eigentlich nicht.

Doch. Genau das ist es in der Praxis.

Ein 300 Zeilen Spaghetti Code Programm kann jeder überblicken. Auch noch 
nach Jahren. NOch ein paar Nullen mehr hinten drann und dann geht das 
nicht mehr.
OOP ist eine Methode, wie man Code strukturiert. Und das tut man, um den 
Code wartbar zu halten.

> Objektorientierte Programmierung hat genau dort ihren Sinn, wo mehrere
> äußerlich gleichartig zu behandelnde, aber innerlich unterschiedliche
> Objekte existieren.

Natürlich. Keiner sagt, dass es nicht mehrere Motivationen für OOP geben 
kann. Das eine schliesst das andere nicht aus. Und oft genug folgt das 
eine aus dem anderen bzw. bedingt es.
Man kann auch mit C oder Fortran oder Pascal oder Algol oder Cobol oder 
... riesige Systeme bauen. Das kann man und das wurde auch schon 
gemacht. Wenn die Entwickler diszipliniert genug sind, sich an einfache 
Prinzipien zu halten, dann ist das überhaupt kein Problem. Aber oft tun 
sie das dann eben nicht. Anstatt eine Funktion aufzurufen, die einen 
einfachen Sachverhalt berechnet, wird dann eben der Funktionsaufruf 
eingespart und an der Aufrufstelle direkt gerechnet. Funktioniert super 
... bis sich dann irgendwann mal die Berechnung ändert und man plötzlich 
in der Situation ist, die 185 Stellen im Code zu finden, an denen die 
Berechnung direkt gemacht wurde (weil man ja 'optimal' programmieren 
will und ein Funktionsaufruf erst mal nur Zeit kostet) anstelle überall 
die eine Funktion aufzurufen, die diese Berechnung durchführt.

Das meine ich mit Disziplin. C hat nichts zu diesem Thema zu sagen und 
vertraut einfach darauf, dass die Programmierer das schon richtig 
machen.

Been there - seen that - took a long time to correct it.

>  lernt vor dem In_Die_Tasten_Hauen doch um himmelswillen wenigstens ein klein 
wenig Logik.

Lern du erst mal, dass es in der Informatik nicht die eine, allein selig 
machende, Methode gibt. Ob und wie ein Klassenaufbau sinnvoll aussieht, 
hängt mehr als alles andere von der konkreten Aufgabenstellung ab.


> Aber ne Klasse "Sensor" und ne klasse "Temperatur" ist
> schlichtweg albern und unsachgemäß.

Ach, ist es das?

> Allein schon aus
> der logischen Erwägung heraus, daß unterschiedliche Sensoren ja
> unterschiedliche Ergebnistypen liefern: ein Thermometer liefert
> was anderes als ne Waage odeer ein Zollstock.

Und?
Warum kann es dann keine gemeinsame Basisklasse SensorWert geben, die 
die Obermenge all dieser unterschiedlichen Werte darstellt? Wieso ist 
das albern? Gerade in so einem Fall, in dem man diverse unterschiedliche 
Typen unter einen Hut bringen möchte, ist das möglicherweise alles 
andere als albern.
Wenn ich das brauche und sinnvoll nutzen kann, weil ich in meiner 
Applikation in einem Grid die Bezeichnung des Wertes, den Wert selber 
und seine Einheit darstellen muss UND ich die Dialogbehandlung 
unabhängig von den tatsächlich möglichen Einheiten der diversen Werte 
bzw. deren Typen haben will, dann ist so eine Basisklasse tatsächlich 
sinnvoll. Oder was denkst du, wie in den diversen IDE's die Anzeigen für 
die einzustellenden Properties eines Items in einem Resource Editor 
realisiert ist? Riesige switch-case Strukturen?
Wieso soll ein geometrisches Item in einem CAD nicht eine PropertyList 
liefern können, in der die diversen Properties dieses Items versammelt 
sind, jedes nicht mehr als eine simple Einstellung (Breite, Höhe, 
Winkel, Beschriftung, Farbe, Name, ...), die vom Anzeigemodul einfach in 
der Form von Properties in die Controls eingebaut wird, indem zb jedes 
Property aufgefodert wird, sich in die Zeile eines Grids reinzurendern? 
Das kann sinnvoll sein. Hängt nur davon ab, welchen Aufwand ich treiben 
muss bzw. will. Wer sagt eigentlich, dass ein Sensor nur einen einzigen 
Wert liefert? Eine IMU liefert mehrere numerische Werte. Was ist mit 
denen?
Genauso wie es nicht albern sein muss, unterschiedliche Sensoren unter 
einer gemeinsamen Basisklasse Sensor in einer Hierarchie zu sammeln. 
Wenn ich es sinnvoll nutzen kann, dann ist das alles andere als albern.

Die Aufgabenstellung bestimmt was sinnvoll ist und was nicht.

> Aber all das ist hier nicht der Fall. Der TO will einen Temperaursensor auslesen

Exakt. Und genau deshalb kann man an so einem Micky Mouse Beispiel nicht 
sinnvoll festmachen, welche Vorteile OOP bringt. Diese Aufgabenstellung 
(und ich rede hier nicht von der Klassenbibliothek zur Anzeige) kann 
sowohl klassisch prozedural als auch mit OOP Methoden gelöst werden, 
wobei der OOP Ansatz erst mal nach einem riesigen Overhead aussieht, den 
keiner (in diesem Beispiel) braucht. Die Moral von der Geschichte ist 
dann oft, dass die Leute sagen, dass OOP nichts bringt, weil ja das 
gleichwertige C Programm um 2/3 kürzer und leichter zu überblicken ist - 
in dieser konkreten Aufgabenstellung. Was OOP tatsächlich bringt und 
leisten kann, sieht man erst in größeren komplexeren Systemen und das 
auch erst dann, wenn man eine zeitlang damit gearbeitet hat. Für einen 
OOP Neuling erschliesst sich der wesentliche Unterschied zwischen 
hierarchischer Ableitung samt virtuellen Funktionen auf der einen Seite 
und switch-case Leisten auf der anderen Seite nicht sofort. Für den ist 
die switch-case basierend auf einer Typangabe erst mal einfacher, da 
kürzer und weniger Tippaufwand. Das die auch fehleranfälliger ist, merkt 
er erst, wenn er zum dritten mal damit auf die Nase gefallen ist, weil 
er in einem der switches die Erweiterung um einen neuen Typ verpennt hat 
und natürlich keinen assert im default hat.

Du warst doch der, der einem C-Programmierer Klassen und Ableitung (und 
damit C++) nahegelegt hat, um auf einem µC mit Touchpad Bereiche 
erkennen zu können. Dabei wollte der Fragesteller einfach nur simple 
Rechtecke haben und nicht mehr. Jetzt wäre eine ähnlich simple 
Aufgabenstellung (mit Potential für mehr) mit OOP Mitteln anzugehen 
plötzlich albern. Bischen inkonsequent, findest du nicht?

: Bearbeitet durch User
von Tom K. (ez81)


Lesenswert?

Markus schrieb:
> Aus eigener Erfahrung kann ich nur ins Feld führen, dass man irgendwann
> mal klein beginnt (kleines Programm), sich die Dinge aber
> unerwarteterweise plötzlich verselbständigen und schnell wachsen.

Aus meiner (begrenzten) Erfahrung ist genau da der Punkt, wo man 
sinnvollerweise innehält und einen Schritt zurücktritt, um 
Programmaufbau + Strukturen der neuen Komplexität anzupassen, 
Basisklassen/Patterns einzuführen und alles soweit wie sinnvoll zu 
abstrahieren. Code darf dabei auch gelöscht und allgemein neugeschrieben 
werden.

Am Anfang mit einem Sensor und einem Fenster mit einer Zahl ist es zu 
früh, weil man noch keinen Überblick hat, was gebraucht werden wird und 
sich zwangsläufig irgendwelche Architekturen zusammenwasserfallt, die 
später nicht funktionieren (alte Hasen ausgenommen).
Bei 20 verschiedenen Sensoren, die über UDP/RS232/GPIB/Brieftaube 
ausgelesen und grafisch dargestellt werden, ist es zu spät, weil man 
einen Haufen switch/case/if/else-Spaghetti hat.

Privat denkt man nicht immer rechtzeitig daran, weil das erstmal keinen 
Spaß macht und keine sichtbaren Ergebnisse liefert; beruflich brüllt 
einem vielleicht jemand ständig "Liefertermin! Das Zeug läuft, nicht 
mehr anfassen, mach neue Features!" ins Ohr.

von Markus (Gast)


Lesenswert?

Tom K. schrieb:
> Aus meiner (begrenzten) Erfahrung ist genau da der Punkt, wo man
> sinnvollerweise innehält und einen Schritt zurücktritt, um
> Programmaufbau + Strukturen der neuen Komplexität anzupassen,
> Basisklassen/Patterns einzuführen und alles soweit wie sinnvoll zu
> abstrahieren. Code darf dabei auch gelöscht und allgemein neugeschrieben
> werden.

Kann ich unterschreiben. :-) Das Innehalten und Zurücktreten schaffen 
aber leider die wenigsten. :-( Auch Profis nicht.

> Privat denkt man nicht immer rechtzeitig daran, weil das erstmal keinen
> Spaß macht und keine sichtbaren Ergebnisse liefert; beruflich brüllt
> einem vielleicht jemand ständig "Liefertermin! Das Zeug läuft, nicht
> mehr anfassen, mach neue Features!" ins Ohr.

Privat ist es auch annähernd egal, wieviel Zeit man in die Wartung von 
Spaghetticode steckt. Beruflich ist das von Dir beschriebene Verhalten 
zwar gängige Praxis, aber leider sehr kurzsichtig.

In (Software-)Systemen, die über einen hinreichend langen Zeitraum 
gepflegt werden müssen, ist dieser Ansatz (Liefertermin, keine Zeit) 
langfristig das Todesurteil für das Produkt. Es ist recht schnell nicht 
mehr mit vernünftigem Aufwand wartbar.

Grüße
Markus

von Yalu X. (yalu) (Moderator)


Lesenswert?

Markus schrieb:
> Die Temperatur als Klasse zu modellieren ist sogar sehr sinnvoll. Eine
> Temperatur hat einen (im Vergleich zu dem skalaren Typ int)
> eingeschränkten Wertebereich. Wenn Du keinen eigenen Typ für die
> Temperatur hast, müsstest Du korrekterweise bei jeder Zuweisung einen
> Range-Check machen. Weiter macht es überaus Sinn, dass die
> Temperaturklasse verschiedene Konvertierungen bietet, z.B. nach String,

Das ist eine interessante Herangehensweise, die ich aber noch nirgends
live gesehen habe. Hast du da vielleicht ein Beispiel irgendeines
Open-Source-Projekts, wo das so gemacht wird?

Das Problem, das ich dabei sehe: Würde man das konsequent durchziehen,
müsste man ja für fast jede Variable eine eigene Klasse definieren, dazu
kommen dann noch unzählige Überladungen für die dafür benötigten
Rechenoperationen (vor allem Multiplikationen und Divisionen, bei denen
die beiden Operanden i.Allg. unterschiedliche physikalische Größen sind
und damit unterschiedlichen Klassen angehören).

Was ich mir in dieser Richtung ganz gut vorstellen kann, ist die
Verwendung unterschiedlicher Klassen abhängig von der Dimension der
jeweiligen physikalischen Größe, da dafür generische Klassen, wie sie
bspw. in der bereits angesprochenen Boost.Units-Bibliothek definiert
sind, verwendet werden können. Auch damit lassen sich schon sehr viele
Fehler in physikalischen Formeln aufdecken, und das sogar schon zur
Compile-Zeit. Nur hat man dort eben keine Überprüfung des Wertebereichs.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Das Problem, das ich dabei sehe: Würde man das konsequent durchziehen,
> müsste man ja für fast jede Variable eine eigene Klasse definieren

Naja, für die Weltformel vielleicht. Für normale Projekte hat man doch 
ein gewisses Domainmodel und da gibt es nicht so wahnsinnig viele 
verschiedene Typen/Klassen.

Yalu X. schrieb:
> dazu kommen dann noch unzählige Überladungen für die dafür benötigten
> Rechenoperationen

Auch hier: Wie oft muss man JEDEN Typ mit JEDEM Multiplizieren, addieren 
etc? Gerade die physikalischen Einheiten (wenn man nicht jenseits des 
Teiches wohnt) sind doch überschaubar und wohldefiniert.

Ein Beispiel findest du hier für Messgrößen (incl. Fehlerabweichung): 
http://www.osgi.org/javadoc/r4v42/org/osgi/util/measurement/package-summary.html
oder für Zeiteinheiten:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html

Es gibt nix blöderes als eine Funktion/Methode welche ein 
long/double/... akzeptiert, der in Wirklichkeit aber ein Datum oder 
Temperatur sein soll. Den da kommt man wirklich schnell hin, wenn viele 
an dem Code arbeiten das dann jeder wie er lustig ist das interpretiert, 
umrechnet und ausgibt, und ob der Wertebereich stimmt ist auch Fraglich.

Und wenn man das konsequent durchzieht, gibt es sehr wenig Stellen 
(Erzeugung, Serialisierung) wo man tatsächlich sich um die internas 
kümmern muss. Hat man dann noch das ganze interfacebasiert aufgebaut 
kann man ein flexibles, wartbares und (modular) erweiterbares System 
schaffen was Fehler von vornherein verhindert und auch noch gut Testbar 
ist.

von W.S. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Du warst doch der, der einem C-Programmierer Klassen und Ableitung (und
> damit C++) nahegelegt hat, um auf einem µC mit Touchpad Bereiche
> erkennen zu können.

Richtig. Ganz genau.
Aber siehst du denn nicht den logischen Unterschied?
Wenn du auf einem Bildschirm verschiedene grafische Elemente 
unterschiedlicher Bauart hast, dann haben selbige zwar ein 
unterschiedliches Innenleben, aber sie sind in mehreren entscheidenden 
Punkten doch einheitlich: Sie haben alle irgendein Aussehen, was 
gezeichnet werden muß. Sie haben zum Teil auch die Notwendigkeit, auf 
Botschaften zu reagieren.

Sie stammen also im Prinzip alle von einem Ancestor ab, der prinzipiell 
genau diese gleichen (virtuellen) Methoden hat: Darstellung und 
Reaktion auf Ereignisse. Ihre vom übergeordneten System sichtbaren 
Eigenschaften sind also kommensurabel (mit gleichem Maß meßbar und in 
gleicher Weise behandelbar).

Bei solchen Dingen wie Sensor und Temperatur trifft das eben NICHT zu. 
Ein Sensor liefert zwar im Allgemeinen eine Zahl, aber das ist eben 
nicht einfach eine Zahl, sondern eine Größe also Zahl plus Maßeinheit. 
Und deshalb sind unterschiedliche Sensoren eben NICHT kommensurabel. Sie 
haben keinen gemeinsamen Ancestor. Das ist der grundlegende Unterschied 
- ich hoffe, daß du das begreifst.

Bei der Temperatur sieht das zwar ganz anders aus, aber es ist auch 
nicht besser: Eine Temperatur ist ein Zahlenwert plus eine Maßeinheit, 
also eine Meßgröße. Daraus eine Klasse machen zu wollen, ist albern. Was 
soll eine Klasse Temperatur denn bieten? Man kann ihr nichts zuweisen, 
sie hat keine innere Struktur, sie ist eine Größe, die man messen und 
zur Kenntnis nehmen kann - nicht mehr. Wer das nicht versteht wie Markus 
kommt dann zu sowas:

Markus schrieb:
> Die Temperatur als Klasse zu modellieren ist sogar sehr sinnvoll. Eine
> Temperatur hat einen (im Vergleich zu dem skalaren Typ int)
> eingeschränkten Wertebereich. Wenn Du keinen eigenen Typ für die
> Temperatur hast, müsstest Du korrekterweise bei jeder Zuweisung einen
> Range-Check machen. Weiter macht es überaus Sinn, dass die
> Temperaturklasse verschiedene Konvertierungen bietet, z.B. nach String,

Der Range-Check ist Mumpitz, da man einer Temperatur nichts zuweisen 
kann. Sie ist - für Programmierer - eine ReadOnly Sache. Man kann sie 
mit einem Sensor erfassen (s.o.) und dessen Ergebnis zum Rechnen oder 
schlichtweg zum Anzeigen verwenden - jedenfalls dessen numerischen Wert 
unter Berücksichtigung der Maßeinheit - womit wir beim übergeordneten 
Programm wären: Weder ein Sensor noch die von ihm gemessene Temperatur 
können riechen, was mit ihrem Meßergebnis denn so geschehen soll. Das 
ist Obliegenheit des Programmes, was das Meßergebnis verwendet und 
dieses muß zwangsläufig Maßzahl und Maßeinheit bei der Verwendung 
berücksichtigen. Sowas könnte weder ein Objekt "Sensor" noch ein Objekt 
"Temperatur" leisten.

Ich nehme mal an, ihr meint etwas ganz anderes: nämlich visuelle Objekte 
in einer grafischen Bibliothek, nennen wir sie mal TSensorDisplay und 
TTemperaturAnzeige. Sowas kann selbstverständlich von einem Ancestor 
TVisual abgeleitet werden wie z.B. TDropDown oder TButton. Sowas kann 
auch auf Botschaften reagieren (neuer Wert eingetroffen) und es kann 
sich zeichnen. Für sowas ist eine Klasse in Ordnung, wenn sie sich in 
den Rest der verwendeten Bibliothek einordnet.

So, Leute, ich leg's euch ans Herz: Lernt das logische Denken und das 
analytische Denken und das naturwissenschaftliche Denken. Im Moment 
könnt ihr nur das Programmierer-Denken. Ist zwar auch was wert, reicht 
aber nicht aus. Guckt über den Tellerrand.

W.S.

von D. I. (Gast)


Lesenswert?

Wieso sollte eine Temperatur read-only sein müssen? Wenn ich eine 
Heizung softwaretechnisch regeln möchte, kann ich sicherlich auch eine 
Temperatur einstellen...

Allein schon die Möglichkeit, dass ich mir ein und dieselbe Temperatur 
in verschiedenen Einheiten geben lassen möchte, bietet sich durch eine 
Klasse an.
1
class Temperature
2
{
3
  private decimal _valueInKelvin;
4
5
  public decimal InKelvin { get { ... }; set { ... }; }
6
  public decimal InCelsius { get { ... }; set { ... }; }
7
  public decimal InFahrenheit { get { ... }; set { ... }; }
8
}

und so kann man auch mit Typen wie Länge, Fläche, usw. verfahren. Was 
Sinn macht, nötig ist und gebraucht wird bestimmt immer die 
Aufgabenstellung.

Obiges stammt sogar aus einem realen Industrieprojekt ;) Da liegen die 
Typen die gebraucht werden im Domainmodel für alle Consumer verwendbar. 
Egal ob ShowTemperatureView1 den Wert nun in K oder 
DoSomethingWithTemperatureViewModelXY den Wert in °C braucht, das Model 
kümmert sich drum.

Und es liest sich dann auch wie ein Roman:
1
if ( mySensorValue.InCelsius > 0 ) { ... }

besser als
1
// sensor value given in K, 273.15 is zero for celsius
2
if ( mySensorValue > 273.15 ) { ... }

Aber wie KH schon sagte, hängt viel davon ab bei welcher 10er-Potenz LOC 
man sich im Projekt bewegt, 10^2 oder 10^6.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

D. I. schrieb:
> Wieso sollte eine Temperatur read-only sein müssen? Wenn ich eine
> Heizung softwaretechnisch regeln möchte, kann ich sicherlich auch eine
> Temperatur einstellen...

Weil es die Handhabung vereinfacht und "unerwartet" verhalten 
eliminiert. Wenn du die Temperatur "ändern" willst, erzeugst du ein 
Objekt mit der Wunschtemperatur und rufst z.B. setTemperatur(t) auf, 
also alles kein Problem.

Der NUTZER einer Temperatur kann nun aber (da er weis das Objekt ändert 
sich nicht mehr) genau dieses hernehmen, er kann es eventuell auch als 
Identifikator für andere Werte hernehmen oder oder, ohne befürchten zu 
müssen das "irgendwer" die inneren Werte des Temperaturobjektes ändert.

Kann er das NICHT müsste er streng genommen das Objekt jedesmal 
kopieren, auch dürfte er sein inneres Objekt nicht ohne weiteres an 
weitere an andere Funktionen weitergeben ohne es zu kopieren (der 
aufgerufen würde es ggf. wieder kopieren und so fort...).


Auch hier gibt es garnicht so viele Fälle wo tatsächlich eine Temperatur 
"erzeugt" oder "geändert" wird, dafür aber viele die die Temperatur 
lesen und da die Temperatur nicht änderbar ist, kann ein 
Temperaturobjekt problemlos geteilt werden, was auch die frage der 
Synchronisation erheblich vereinfacht!

D. I. schrieb:
> dass ich mir ein und dieselbe Temperatur in verschiedenen Einheiten
> geben lassen möchte, bietet sich durch eine Klasse an

Nein, siehe mein Kommentar, so was gehört nicht in die Klasse/Interface! 
Denn das Ergebnis ist nicht von (privaten) inneren Zuständen abhängig 
sonder einzig und allein von den von außen zugreifbaren Werten, ene 
"TmeperaturConversion" Klasse ist hier also sehr viel sinnvoller und 
flexiebler falls morgen jemand eine Temperatur unbedingt als bytearray 
oder oder oder benötigt...

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

D. I. schrieb:
> Wieso sollte eine Temperatur read-only sein müssen? Wenn ich eine
> Heizung softwaretechnisch regeln möchte, kann ich sicherlich auch eine
> Temperatur einstellen...

Nein, das kannst du nicht. Stattdessen kannst du einem Regler einen 
Sollwert vorgeben - das ist etwas anderes. Mag sein, daß du dafür das 
Wort "Temperatur" benutzt, aber das ist unexakt.

Im Grunde hast du in deinem Beispiel eine Klasse TRegler, wo du einen 
Sollwert vorgeben kannst, vllt. SollTemperatur genannt. Aber du hast 
keine Klasse TTemperatur, die du einstellen kannst.

Allenfalls hast du in deiner Regler-Klasse eine readonly Property namens 
MomentanTemperatur oder so ähnlich.

W.S.

von Oliver (Gast)


Lesenswert?

W.S. schrieb:
> Bei solchen Dingen wie Sensor und Temperatur trifft das eben NICHT zu.
> Ein Sensor liefert zwar im Allgemeinen eine Zahl, aber das ist eben
> nicht einfach eine Zahl, sondern eine Größe also Zahl plus Maßeinheit.
> Und deshalb sind unterschiedliche Sensoren eben NICHT kommensurabel. Sie
> haben keinen gemeinsamen Ancestor.

Darüber kann man jetzt lang und breit diskutieren, wie über alles andere 
auch. Was ein Sensor ist, kann und darf sich jeder selber definieren, 
und ob dann da eine Basisobjekt "Sensor" und davon abgeleitete 
Spezifizierungen sinvoll sind, oder nur gemeinsame Interfaces, oder 
sonst eine Lösung, ist nicht mit einem pauschalen Nein zu beantworten.

Aber im Fall des TO ist das ja alles auch sowieos völlig egal. Der will 
EINEN Sensor auslesen. Ob das jetzt per OOP oder mit unabhängigen 
Funktionen oder in Assembler oder optimal oder suboptimal oder sonstwie 
gemacht wird, was solls.

Wenn da eine Bedienoberfläche in C# für Windows dazu kommt, wird die 
sowieso 99% des Programmumfangs umfassen, und Struktur und Ablauf des 
Programms objektorientiert vorgeben. Ob die Sensorbehandlung dann auch 
in eine eigene Klasse wandert, oder nicht, ist völlig nebensächlich.

Oliver

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

W.S. schrieb:
> Ein Sensor liefert zwar im Allgemeinen eine Zahl, aber das ist eben
> nicht einfach eine Zahl, sondern eine Größe also Zahl plus Maßeinheit.

Man könnte es auch MESSWERT nennen (Zahl+Fehler+Einheit), das ist doch 
etwas was allen Sensoren eigen ist.

> Bei der Temperatur sieht das zwar ganz anders aus, aber es ist auch
> nicht besser: Eine Temperatur ist ein Zahlenwert plus eine Maßeinheit,
> also eine Meßgröße. Daraus eine Klasse machen zu wollen, ist albern. Was
> soll eine Klasse Temperatur denn bieten? Man kann ihr nichts zuweisen,
> sie hat keine innere Struktur, sie ist eine Größe, die man messen und
> zur Kenntnis nehmen kann - nicht mehr.

Sehe ich nicht so, wenn ich eine Temperatur haben will, dann will ich 
eine Temperatur und kein beliebeigen double in Kilogram. Also wieso 
nicht temperatur von der generischen Klasse/Interface 'Meßgröße' welche 
ein double und eine Einheit liefert ableiten? Wer mit allgemeinen 
'Meßgrößen' arbeiten kann kann diese ja nutzen, wer explizit wenigstens 
eine Temperatur benötigt kann dies in seiner Methode dokumentieren und 
der Compiler kann das im Vorfeld prüfen.

Hier in "nicht-klassen-würdige" Objekte unterscheiden zu wollen ist 
nicht zielführend. Ob eine direkte VERERBUNG Sinn macht ist ein ganz 
andere Punkt, ich habe ja schon oben geschrieben, das man sowas eher 
interface-basiert machen sollte, und die entscheidung ob Vererbung oder 
nicht der implementierung überlassen.

von Georg (Gast)


Lesenswert?

Hallo,

nach der (angeblich erstrebenswerten) MVC-Architektur 
(Model-View-Controller) gehören Umrechnungen der internen Temperatur in 
Fahrenheit, Reaumur oder sonstwas eindeutig nicht zum Model, sondern zum 
View (Ausgabe) oder Controller (Eingabe). Was der intern verwendete Wert 
darstellt, z.B. float Kelvin, müssen natürlich alle Beteiligten wissen!

Es wäre ja absurd, wenn ein Temperaturregler mit einer anderen internen 
Grösse arbeiten würde, nur weil das Gerät nach Frankreich oder USA 
geliefert wird. Auch darf eine Erweiterung der Software um weitere 
provinzielle Masseinheiten überhaupt keinen Einfluss auf die Regelung 
haben.

Georg

von D. I. (Gast)


Lesenswert?

Läubi .. schrieb:
> D. I. schrieb:
>> Wieso sollte eine Temperatur read-only sein müssen? Wenn ich eine
>> Heizung softwaretechnisch regeln möchte, kann ich sicherlich auch eine
>> Temperatur einstellen...
>
> Weil es die Handhabung vereinfacht und "unerwartet" verhalten
> eliminiert. Wenn du die Temperatur "ändern" willst, erzeugst du ein
> Objekt mit der Wunschtemperatur und rufst z.B. setTemperatur(t) auf,
> also alles kein Problem

... mh könnte meinen Vorschlag auch als struct realisieren und es 
kombinieren mit deinem:

Regler.setTemperature(Temperature t)

@MVC: Umrechnungnen sehe ich sehr wohl als Model-Logik, die View 
entscheidet lediglich was sie darstellen möchte. Maximal noch im 
Controller, aber bei MVC greift im Zweifel die Faustregel "thin 
controllers, fat models".

von W.S. (Gast)


Lesenswert?

Läubi .. schrieb:
> Sehe ich nicht so, wenn ich eine Temperatur haben will, dann will ich
> eine Temperatur und kein beliebeigen double in Kilogram. Also wieso
> nicht temperatur von der generischen Klasse/Interface 'Meßgröße' welche
> ein double und eine Einheit liefert ableiten?

Wozu, wozu, WOZUHUHUHUHU bloß?
Als akademische Programmierer-Übung ohne Realitätsbezug?
Als Selbstverwirrung?

Kommt demnächst ein Programmierer auf die Idee, einem TKörper eine 
TMasse zuweisen zu wollen? Nun, die Schönheitsindustrie würde das ja 
begrüßen, man könnte damit sich selbst sein Idealgewicht zuweisen, auch 
dann, wenn man nicht ißt sondern frißt. Die Damen werden es den 
Programmierern danken.

Ich hab das hier grad anderswo zitiert (aus dem Stroustrup): "Language 
shapes the way we think, and determines what we can think about"

Ihr habt offensichtlich schon zuviel C++ verinnerlicht, so daß ihr aus 
dieser Denke nicht mehr herauskommt und den Wald vor Bäumen nicht mehr 
seht.

Läubi .. schrieb:
> wer explizit wenigstens
> eine Temperatur benötigt kann dies in seiner Methode dokumentieren

Ja, eben: An was für eine Methode hast du denn bei einer Temperatur 
gedacht? Ist es überhaupt denkbar, daß ein physikalischer Meßwert 
eingebaute Methoden oder Properties hat (eben außer seinem tatsächlichen 
Wert)? Nein, natürlich nicht.

Das äußerste, was hier in Programmiererkreisen denkbar ist, ist eine 
API-Funktion des Betriebssystems, mittels derer man eine Aussage über 
eine Temperatur erfragen kann (Beispiel: aktuelle CPU-Temperatur). Das 
gibt ne Zahl und die Maßeinheit liest man in der BS-Doku nach. Wo 
bittesehr siehst du hier eine auch nur ansatzweise Möglichkeit, 
irgendwelche Methoden unterzubringen?

Läubi .. schrieb:
> Sehe ich nicht so, wenn ich eine Temperatur haben will, dann will ich
> eine Temperatur und kein beliebeigen double in Kilogram.
Nee, du kriegst vom BS eine Zahl und was die bedeutet - siehe oben.
Mehr ist nicht drin in der Tüte.
Jetzt kannst du dich natürlich hinsetzen und dir sagen: "Ich bau mir da 
jetzt ne Breitseite von allem ein, was mir grad einfällt und dann hab 
ich Methoden und Properties bis zum Abwinken." Aber wo bleibt da der 
eigentliche Sinn bei der derart kreierten TYaluTemperaturClass?

W.S.

von W.S. (Gast)


Lesenswert?

.. zum Mitschreiben: YetAnotherLousyTemperatureClass

von Markus (Gast)


Lesenswert?

Don't feed the troll anymore...

von MaWin (Gast)


Lesenswert?

Zumindest dauert es jetzt 5 Tage, und bis sich die Experten über eine 
korrekte TemperaturKlasse einig sein werden scher noch mal 5 Monate, und 
innerhalb von 5 Minuten hätte man das Programm ohne OOP fertig 
geschrieben.

Das kostet dann ein tausendstel (Aufwand, Geld), aber OOP ist ja SOOO 
arbeitssparend.

Und nach 5 Monaten stellt dann die versammelte Programmierertruppe fest, 
daß der erzeugte Code leider nicht in den Programmspeicher des 
anvisierten Microcontroller passt, weswegen ein redesign mit refactornig 
für eine leightweight TemperaturKlasse notwendig ist, nicht ohne externe 
Beratung einzuholen obwohl man doch beratungsresistent ist.

Die Branche ist so verkotzt inzwischen.

von D. I. (Gast)


Lesenswert?

Nein, du bist nur in den 70ern stehen geblieben und bist wahrscheinlich 
frustriert weil du nicht mithalten konntest.

von W.S. (Gast)


Lesenswert?

D. I. schrieb:
> Nein, du bist nur in den 70ern stehen geblieben..

nanananana..

Ständig nur beleidigt (und dann beleidigend) zu reagieren, wenn die 
Argumente ausgehen und dann zu schreiben "du hast ja keine Ahnung" oder 
"du bist ja sooo doof" usw. hilft niemendem.

Es legt auch beredtes Zeugnis ab davon, daß der Schreiber am Verstehen 
der ihm nicht schmeckenden Argumente gescheitert ist, aber seinen zu 
kleinen Horizont einfach nicht zugeben will.

W.S.

von D. I. (Gast)


Lesenswert?

W.S. schrieb:
> Es legt auch beredtes Zeugnis ab davon, daß der Schreiber am Verstehen
> der ihm nicht schmeckenden Argumente gescheitert ist, aber seinen zu
> kleinen Horizont einfach nicht zugeben will.

MaWin mag von Elektrotechnik große Ahnung haben, aber sein 
Softwarehorizont reicht nicht über 100 Zeilen Mikrocontroller hinaus, 
das hatten wir im Forum aber schon gefühlte 1000 mal. Da gibts mit KH, 
Läubi, Yalu etc. andere Kompetenzen.
Natürlich kann man immer erstmal was zusammenhacken was irgendwie tut, 
so siehts dann hinterher auch aus und so wartbar isses dann auch. Btw. 
MaWin sollte der letzte sein, der sich darüber beschweren kann in einem 
ranzigen Ton angeredet zu werden.
Edit: Du hast auch auch keine sonderlich ernstzunehmende Argumente 
gebracht, deswegen lohnt es sich nicht mit euch beiden weiter über 
dieses Thema zu diskutieren.

von Vlad T. (vlad_tepesch)


Lesenswert?

Andreas Lang schrieb:
> [...] Die Sensorklasse wird dann für jeden sensortyp abgeleitet, wenn ich [...]

Hier vermengst du doch Hardware mit Software.
Klasse Temperatur sollte sich nur um solche kümmern.
Dieser Teil ist Applikationsspezifisch komplett hardwareunabhängig.

Genauso wie es eine I²C Klasse geben sollte, die sich nur um die 
Ansteuerung der Schnittstelle kümmert und der egal ist, was mit den 
geholten Daten passiert, oder wie sie zu interpretieren sind.
Der Teil ist natürlich hardwareab- aber anwendungunabhängig. Klassischer 
Treibersoftware halt.

Dazwischen sitzt eine Ebene, HAL (Hardware Abstraction Layer) genannt, 
die deine konkrete Application an die Hardware koppelt. Sie sagt dem I²C 
"hol die Daten" und rechet sie (bestenfalls in SI-Einheiten) um und 
übergibt sie der Applikation.

Das ganze ist unabhängig von Programmiersprache oder OOP oder Nicht-OOP.

Gehst du auf eine neue Hardware musst du nur passende Treiber suchen und 
den HAL anpassen. Bringst du eine andere Anwendung auf die bekannte 
Hardware, musst du nur den HAL anpassen. Schreibst du eine neue 
Anwendung für eine neue Hardware musst du halt alle drei Komponenten 
schreiben, aber meist finden sich zumindest Treiber schon irgendwo.
Bastelst du ein µC Projekt, wo abzusehen ist, dass du die Hardware das 
erste und letzte mal siehst und das nicht sehr komplex ist und nicht 
gewartet werden soll, vermischt man halt Application und HAL. Treiber 
würd ich trotzdem immer extra halten.

von Quack (Gast)


Lesenswert?

Kevin schrieb:
> In wie weit organisiert man alles in Klassen?

Nun, Kevin - wie du hier lebhaft sehen kannst, ist es am Besten, du 
findest deinen eigenen Weg. Probiere aus, betrachte deine Loesungen 
selbstkritisch, verbessere sie. Schau hin und wieder ueber den 
Tellerrand und lasse dich inspirieren. Aber auf keinen Fall solltest du 
dir etwas von anderen Vorbeten lassen oder irgendwelchen Goetzen 
nacheifern.

Finde deinen Weg.

von MaWin (Gast)


Lesenswert?

D. I. schrieb:
> Nein, du bist nur in den 70ern stehen geblieben und bist wahrscheinlich
> frustriert weil du nicht mithalten konntest.

Im Gegensatz zu dir ist mein Programm schon längst fertig und verkauft 
sich prächtig und bringt Millionen ein.

Dein Geschwätz hingengen ist sachlich falsch, und das weiss ich, 
deutlich besser als du, denn du redest über mich.

Und so weiß ich auch vieles andere deutlich besser als du.

von W.S. (Gast)


Lesenswert?

D. I. schrieb:
> Du hast auch auch keine sonderlich ernstzunehmende Argumente
> gebracht

Hast du irgend etwas Ernstzunehmendes dagegen zu setzen?
Nein?

Hast du wenigstens eine Ergänzung, eine Weiterführung, eine Präzisierung 
- kurzum irgend etwas Sachliches dazu zu sagen?
Auch nein?

Dann laß solche Bemerkungen und gehe das nächste Mal wenigstens ein 
wenig auf das ein, was ich geschrieben habe.

Wie gesagt: einfach bloß "du bist ja doof" zu schreiben reicht einfach 
nicht aus. Gilt auch für dich.

W.S.

von Georg (Gast)


Lesenswert?

MaWin schrieb:
> schon längst fertig und verkauft
> sich prächtig und bringt Millionen ein.

Und warum fängst du dann hier im Forum einen blödsinnigen Streit nach 
dem anderen an, statt dich in St. Tropez auf deiner Yacht zu sonnen?

Georg

von Kevin (Gast)


Lesenswert?

Quack schrieb:
> Kevin schrieb:
>> In wie weit organisiert man alles in Klassen?
>
> Nun, Kevin - wie du hier lebhaft sehen kannst, ist es am Besten, du
> findest deinen eigenen Weg. Probiere aus, betrachte deine Loesungen
> selbstkritisch, verbessere sie. Schau hin und wieder ueber den
> Tellerrand und lasse dich inspirieren. Aber auf keinen Fall solltest du
> dir etwas von anderen Vorbeten lassen oder irgendwelchen Goetzen
> nacheifern.
>
> Finde deinen Weg.

Vielen Dank für deine Einschätzung. Aktuell sieht es ja so aus, als wenn 
das sowieso jeder völlig anders angehen würde.

Gruß,
Kevin

von Fred (Gast)


Lesenswert?

Es wird immer Leute geben, die alles Neue verteufeln und mit dem Alten 
"Millionen verdienen". Das ist ja nicht schlimm. Wenns so funktioniert, 
ist ja gut.

Tragisch ist nur, wenn das für sie Neue schon bald fünfzig Jahre alt 
ist. eg

von Moby (Gast)


Lesenswert?

Fred schrieb:
> Tragisch ist nur, wenn das für sie Neue schon bald fünfzig Jahre alt
> ist. eg

Und selbst wenns 200 wären...
Eine gute Lösung bleibt eine gute Lösung. Insbesondere wenn sie einfach 
ist. Das "Neue"  gibts leider oft nur im Bundle mit mehr, nur allzuoft 
unnötiger Komplexität.

von Moby (Gast)


Lesenswert?

Kevin schrieb:
> Vielen Dank für deine Einschätzung. Aktuell sieht es ja so aus, als wenn
> das sowieso jeder völlig anders angehen würde

Da gibts eben die OOP Theologen, deren Lösung schön komplex sein muß, 
damit dieses Blendwerk ordentlich was hermacht und solche, die nur und 
genau das programmieren, was der Problemstellung tatsächlich angemessen 
ist.

von W.S. (Gast)


Lesenswert?

Naja, kommen wir mal zum eigentlichen Kern der Sache zurück:

Kevin schrieb:
> Muss ich also eine Klasse "Temperatur" anlegen? (hier könnte man ja
> zwischen Fahrenheit und Celsius unterscheiden?
>
> Außerdem muss ich ja sicher eine Klasse Sensor anlegen. Wie weit würde
> man das ganze noch aufdroeseln?

Es kommt drauf an, was du willst:
a) üben, wie man ne Klasse anlegt?
b) auf deinem PC auf der grafischen Oberfläche ein Fenster haben, wo dir 
die aktuelle Temperatur entgegengrinst?
c) auf deinem PC ein Tool haben, also ein biederes 
Kommandozeilenprogramm von stdin nach stdout, oder den aktuellen 
Temperaturwert in eine Datei schreiben?
d) der Frage nachgehen, was man sinnvoll in C++ oder auch in anderen 
Sprachen, die OOP bieten, in Objekte quetscht oder eben auch nicht?

Ganz allgemein sag ich dazu, daß es zu allererst nötig ist, sich mit 
sich selber über die Begrifflichkeiten ins Klare zu kommen: Eine Klasse 
"Temperatur" ist albern, eine Klasse "Temperatur_Adapter" oder 
"Temperatur_Anzeiger" oder "Temperatur_Regler" hingegen nicht. es kommt 
auf den beabsichtigten Inhalt an, also was da innerhalb des Objektes 
'leben' soll. Für ein stupides 'double' wäre eine eigene Klasse 
übertrieben bis zur Albernheit, für z.B. einen PID-Regler hingegen sieht 
das völlig anders aus.

W.S.

von Georg (Gast)


Lesenswert?

Moby schrieb:
> solche, die nur und
> genau das programmieren, was der Problemstellung tatsächlich angemessen
> ist.

Ich stelle mir gerade so vor, wie dich beim Einstellungsgespräch der 
Personalchef fragt, ob du Erfahrungen mit OO hast, und du antwortest 
"ich programmiere nur das, was der Problemstellung tatsächlich 
angemessen ist"...

Ich habe ja weiter oben das Beispiel gebracht mit einer Klasse Bit mit 
Getter/Setter für true und false und Methoden für and, or, xor, sowas 
macht einfach viel mehr her. War übrigens keine Fantasie von mir, das 
gibt es wirklich, sogar als verbindliche Lösung. Die Sprache hiess 
Actor, von Whitewater.

Georg

von Moby (Gast)


Lesenswert?

Georg schrieb:
> Ich stelle mir gerade so vor, wie dich beim Einstellungsgespräch der
> Personalchef fragt...

Der fragt aber nicht, Georg. Als Bastler hat man eben den  einzigartigen 
Luxus, sich auf das tatsächlich notwendige beschränken zu können :-)

von Moby (Gast)


Lesenswert?

W.S. schrieb:
> übertrieben bis zur Albernheit

Genau das ist OOP- zumindest für alle jene Millionen Problemstellungen, 
die nicht über ein bestimmtes Maß an Komplexität hinausgehen. Hinter der 
softwaretechnisch eleganten Anmutung steckt allein unnötiger Overhead 
und Dokumentationsbedarf. Aber schee schauts aus- und trefflich 
akademisch diskutieren lässt sich darüber auch.

von Georg (Gast)


Lesenswert?

Moby schrieb:
> unnötiger Overhead

Ich habe mal versucht mich zu erinnern wie man OO-mässig addiert:

aus der Gleichung
s = x + y
die man in "normalen" Programmiersprechen genauso eingibt, wird bei 
Actor:

s.SetValue (x.AddValue (Y.GetValue));

supereindrucksvoll und sooo übersichtlich, nicht?

Georg

von Peter (Gast)


Lesenswert?

Georg schrieb:
> s.SetValue (x.AddValue (Y.GetValue));
>
> supereindrucksvoll und sooo übersichtlich, nicht?

Schon mal von Operatorüberladung gehört?

von Stefan R. (srand)


Lesenswert?

Ja, Spielzeug-Einzeiler sind immer eine gute Grundlage für einen 
fundierten Vergleich.

von Jan H. (j_hansen)


Lesenswert?

Georg schrieb:
> Ich habe mal versucht mich zu erinnern wie man OO-mässig addiert:
>
> aus der Gleichung
> s = x + y
> die man in "normalen" Programmiersprechen genauso eingibt, wird bei
> Actor:
>
> s.SetValue (x.AddValue (Y.GetValue));
>
> supereindrucksvoll und sooo übersichtlich, nicht?

Ich kenne Actor nicht, aber scheint ja eine reichlich antiquierte 
Sprache zu sein. Kein Wunder, dass du da keinen Spaß daran hattest. 
Außerdem ist das was du hier machst nicht wirklich der OO-Weg. Wenn ich 
mit objektorientiert-funktionalem Denken Assembler programmiere, kann 
ich auch nicht einfach Zeile für Zeile übersetzen.

Zu deinem Beispiel: sollte man das wirklich so brauchen, dann gibt es 
dafür im Normalfall Operatorüberladung und primitive Typen. Dann bleibt 
es auch bei s = x + y.

Je nach Aufgabenstellung hat man aber oft andere Fälle, z.B. addiere 
eine Länge zu einer anderen Länge:
s = x.add(y)
Das ist, finde ich, schon ganz nett. Sobald x und y nicht mehr die 
gleiche Einheit haben kann man die Umrechnung schön in der Add-Methode 
kapseln. Und wenn ich mich vertippe und zur Länge eine Temperatur 
addieren möchte schreit der Compiler.

von Oliver S. (oliverso)


Lesenswert?

Moby schrieb:
> und solche, die nur und
> genau das programmieren, was der Problemstellung tatsächlich angemessen
> ist.

Genau die, die immer nur das programmieren, was der Aufgabenstellung 
angemessen ist, haben überhaupt zur Entwicklung der höheren 
Programmiersprachen und danach zu deren Weiterentwicklung geführt.

Warum wohl nur?

Oliver

von Georg (Gast)


Lesenswert?

Peter schrieb:
> Schon mal von Operatorüberladung gehört?

Jan Hansen schrieb:
> dann gibt es
> dafür im Normalfall Operatorüberladung und primitive Typen.

Da habt ihr garnichts verstanden. Actor war als streng OO konzipiert, 
d.h. Operatoren gibt es nicht. Punkt. Das hätten die Erfinder als 
Rückfall in die Primitivität abgelehnt (wie Jan sagt: primitive Typen. 
Die gab es natürlich ebensowenig wie Operatoren). Ausserdem wäre das ja 
inkonsequent: wenn man z.B. integer mit dem Operator + addieren kann, 
wozu muss ein integer dann noch ein Objekt einer Klasse sein? Was soll 
denn vererbt werden, wenn nicht Methoden wie Add?

Actor wurde gleich nach den ersten Erwähnungen von OO als die ultimative 
Lösung mit vollständiger Umsetzung des OO-Gedankens propagiert, ist aber 
bald in der Versenkung verschwunden. Nach meiner Ansicht zu Recht, und 
das sollte mein Beipiel begründen. Ich würde das als fundamentalistische 
OO bezeichnen.

Georg

von Yalu X. (yalu) (Moderator)


Lesenswert?

Georg schrieb:
> Da habt ihr garnichts verstanden. Actor war als streng OO konzipiert,
> d.h. Operatoren gibt es nicht. Punkt.

Warum widerspricht die Verwendung von Operatoren dem objektorientierten
Programmierparadigma?

Falls dich der Bergiff "Operator" stört: Benenne ihn einfach um, bspw.
in "Methode mit 1 Argument" (wie in C++) oder "binäre Nachricht" (wie in
Smalltalk).

Falls dich die Schreibweise mittels Sonderzeichen ('+'. '-' usw.) stört:
Das ist ausschließlich eine Frage der Syntax, nicht des Paradigmas.

> Ich würde das als fundamentalistische OO bezeichnen.

Wenn allgemein anerkannte und der Lesbarkeit dienende syntaktische
Konstrukte wie die Infixnotation arithmetischer Ausdrücke sinnloserweise
einem übertriebenen OO-Wahn geopfert werden, würde ich das schon eher
als extremistische OO bezeichnen ;-)

von Georg (Gast)


Lesenswert?

Yalu X. schrieb:
> Falls dich die Schreibweise mittels Sonderzeichen ('+'. '-' usw.) stört:
> Das ist ausschließlich eine Frage der Syntax, nicht des Paradigmas.

Das ist mir schon klar, dass das alles geht und auch gehen sollte, aber 
die damaligen Macher haben das im Interesse der reinen Lehre eben nicht 
vorgesehen. Könnte man die Addition mit + schreiben, wäre der 
beabsichtigte erzieherische Effekt hin zu OO ja nicht mehr gegeben 
gewesen. Aber lassen wir solche Verirrungen in Frieden ruhen, ausser mir 
erinnert sich sowieso keiner mehr an Actor (immerhin findet Google noch 
was).

Georg

von Jan H. (j_hansen)


Lesenswert?

Georg schrieb:
> Aber lassen wir solche Verirrungen in Frieden ruhen, ausser mir
> erinnert sich sowieso keiner mehr an Actor (immerhin findet Google noch
> was).

Die Frage ist, warum du diese "Verirrung" dann gegen OO in Stellung 
bringst.
Vielleicht solltest du dir eine modernere Sprache ansehen - vielleicht 
wirst du ja noch ein Fan :)

von Moby (Gast)


Lesenswert?

Oliver S. schrieb:
> Genau die, die immer nur das programmieren, was der Aufgabenstellung
> angemessen ist, haben überhaupt zur Entwicklung der höheren
> Programmiersprachen und danach zu deren Weiterentwicklung geführt.

Für komplexe Problemstellungen braucht es sicher neue Herangehensweisen. 
OOP ist ein mehr oder weniger gelungener Versuch dazu.
Die Problemstellung des TO gehört wie Millionen andere sicher nicht 
dazu. OOP ist eben KEIN passendes Universalwerkzeug für alle Fälle.
Aber wer einen tollen Hammer in der Hand zu halten glaubt neigt 
natürlich dazu, in jedem Problem einen Nagel zu sehen ;-)

Der Begriff "Einfachheit" hat im übrigen auch etwas doppelbödiges an 
sich. Der sich entwickelnde Profi wird darunter etwas anderes verstehen 
als der Bastelamateur. Laufend werden Programmiersprachen 
weiterentwickelt und um neue Konstrukte erweitert, die dem Profi im 
konkreten Fall Vereinfachung versprechen, das ganze System aber 
letztlich aufblasen und dann doch immer komplizierter = lernintensiver 
machen. Egal. Wenn irgendwann kaum einer mehr einsteigt ist jedes System 
sowieso zum Untergang verurteilt.

Georg schrieb:
> im Interesse der reinen Lehre...

und nach strikten pauschalen Regularien / Programmierideologien wird man 
selten zur passgenauen, einfachsten Lösung finden.

von Oliver S. (oliverso)


Lesenswert?

Moby schrieb:
> OOP ist ein mehr oder weniger gelungener Versuch dazu.
> Die Problemstellung des TO gehört wie Millionen andere sicher nicht
> dazu.

Der TO programmiert aus Spaß, hat bisher keine Erfahrung mit OOP, und 
möchte da einfach mal Erfahrung sammeln. Das macht das mir einer 
einfachen Anwendung. Ist doch völlig in Ordnung. Ja, das Problem lässt 
sich (als Konsolenanwendung) mit ein paar Zeilen Assembler erschlagen, 
aber darum geht es doch gar nicht.

Oliver

von Mark B. (markbrandis)


Lesenswert?

Kevin schrieb:
> Muss ich also eine Klasse "Temperatur" anlegen? (hier könnte man ja
> zwischen Fahrenheit und Celsius unterscheiden?

Eine Klasse "Temperatur" ergibt generell wenig bis gar keinen Sinn. 
Genau so, wie eine Klasse "Zeit" oder "Länge" oder "Stromstärke" oder 
"Volumen" wenig bis gar keinen Sinn ergibt.

Physikalische Größen wird man in der OOP in aller Regel als eine 
"hat-ein" Beziehung antreffen. Also:

-ein Fahrzeug hat eine Geschwindigkeit v
-ein Gegenstand hat eine Masse m
-ein Temperatursensor hat einen Temperaturwert ϑ (Theta)

Eine "hat-ein" Beziehung wird man in den Member-Variablen wiederfinden, 
über die eine Klasse verfügt. Und in den Methoden, die darauf operieren.

> Außerdem muss ich ja sicher eine Klasse Sensor anlegen. Wie weit würde
> man das ganze noch aufdroeseln?

Man kann eine Basisklasse "Sensor" anlegen, von der man dann alle 
anderen Sensoren ableitet. Das ist im Gegensatz zu oben eine "ist-ein" 
Beziehung. Die "ist-ein" Beziehung findet sich in der Klassenhierarchie 
wieder. Also:

-ein Temperatursensor ist ein Sensor
-ein Helligkeitssensor ist ein Sensor
-ein Feuchtigkeitssensor ist ein Sensor

und so weiter. Zu Übungszwecken: Warum nicht. In einer realen Anwendung 
auf einem Mikrocontroller, auf dem überhaupt nur ein einziger Sensor 
existiert: Unnötiger Mehraufwand. In einem Projekt, in dem es eine 
Vielzahl von unterschiedlichen Sensoren gibt: Kann sinnvoll sein. Ob es 
das ist oder nicht, hängt immer von der konkreten Aufgabenstellung ab.

: Bearbeitet durch User
von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Geschwindigkeit

Eine Geschwindigkeit hat einen Numerischen Wert und eine Einheit

> Masse

Eine Masse hat einen Numerischen Wert und eine Einheit

> Temperaturwert

Ein Temperaturwert hat...

Also wieso sollten diese nicht (von der gemeinsamen Basisklasse 
Messgröße) abgeleitete konkrete Klassen sein?

Ob etwas "Sinn hat" ergibt sich nicht aus der Sache sondern aus dem 
Kontext. Ein µC mit 2x16 LCD für die Anzeige der Raumtemperatur hat ganz 
andere Anforderungen als eine Simmulationssoftware für Wetterphänomene.

von Georg (Gast)


Lesenswert?

Läubi .. schrieb:
> Ein Temperaturwert hat...

Ja, aber die Masseinheit mitzuführen ist unsinnig. Wann immer ich mit 
Temperaturen zu tun habe, verwende ich die absolute Temperatur in 
Kelvin, es gibt einfach keinen vernünftigen Grund, mit etwas anderem zu 
rechnen. Also brauche ich auch keine Eigenschaft Masseinheit, sondern 
nur den Zahlenwert.

Noch krasser bei CAD-Systemen: alle mir bekannten Systeme haben eine 
interne Masseinheit, z.B. nm. Alle linearen Masse haben diese Auflösung, 
es wäre daher völlig unsinnig, bei z.B. Tausenden von Pin-Positionen auf 
einer Leiterplatte bei jeder einzelnen die Tatsache mitzuspeichern, dass 
es sich um nm handelt. Auf dem Bildschirm wird sowieso zwischen einer 
ganzen Reihe von Einheiten umgeschaltet, da ist die Anzeigesoftware für 
die Umrechnung zuständig.

Falls man das überhaupt je braucht, kann man im Handbuch nachlesen, was 
die native Einheit des Systems ist. Natürlich kann ein Idiot etwas 
falsch interpretieren, aber gegen Idioten hilft auch OO nicht, die muss 
man halt vom Programmieren fernhalten.

Ich weiss schon, dass es heute absolut uncool ist, Speicherplatz zu 
sparen, aber deswegen muss man ihn ja nicht vollkommen sinnlos 
einsetzen.

Georg

von Moby (Gast)


Lesenswert?

Georg schrieb:
> Ich weiss schon, dass es heute absolut uncool ist, Speicherplatz zu
> sparen,

und Rechenleistung noch dazu. Die Hardware muß immer fetter werden um 
die zunehmend ineffiziente Programmierung auszugleichen. Bis nix mehr 
geht und ein Systemwechsel unausweichlich wird ;-(

von Mark B. (markbrandis)


Lesenswert?

Läubi .. schrieb:
> Mark Brandis schrieb:
>> Geschwindigkeit
>
> Eine Geschwindigkeit hat einen Numerischen Wert und eine Einheit
>
>> Masse
>
> Eine Masse hat einen Numerischen Wert und eine Einheit
>
>> Temperaturwert
>
> Ein Temperaturwert hat...
>
> Also wieso sollten diese nicht (von der gemeinsamen Basisklasse
> Messgröße) abgeleitete konkrete Klassen sein?

Kann man machen, aber was genau bringt das?

Intern wird man für gleiche physikalische Größen auch mit der gleichen 
Skalierung rechnen. Von daher sehe ich es so wie Georg, die Einheit wird 
für die Berechnungen an sich nicht als eine Eigenschaft in einer Klasse 
mit abgespeichert. Ein Meter pro Sekunde ist dann intern in einer 
Variablen nicht als ein Zahlenwert 1 gespeichert, sondern vielleicht als 
10 oder 100 oder 1000. Also skaliert, damit man in Integer-Arithmetik 
mit ganzen Zahlen auch (sehr) kleine Geschwindgkeiten ausdrücken kann.

Anders mag es bei der GUI aussehen. Hier stellt man vielleicht in 
Kilometern pro Stunde dar, was intern mit skalierten Metern pro Sekunde 
gerechnet wird. Das ist aber ein Problem der Anzeige, keines der 
Berechnung. Rechnen wird man alles in der gleichen, vorher festgelegten 
Skalierung, weil es anders wenig sinnvoll wäre.


Läubi .. schrieb:
> Ein µC mit 2x16 LCD für die Anzeige der Raumtemperatur hat ganz
> andere Anforderungen als eine Simmulationssoftware für Wetterphänomene.

Selbst bei Letzterer würde es mich wundern, wenn sowohl 
Windgeschwindigkeit als auch Niederschlagsmenge als auch Luftdruck als 
auch Temperatur alle von der gleichen Basisklasse abgeleitet sind. Falls 
es doch so ist, lasse ich mich gerne eines Besseren belehren.

: Bearbeitet durch User
von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Kann man machen, aber was genau bringt das?

Weniger nötiges Spezialwissen 
(http://de.wikipedia.org/wiki/Truck_Number), (Dein Beispiel zeigt es 
doch gut, "vielleicht skaliert", "vielleicht 10, 100, 1000"... was 
interessiert die interne Repräsentation?), Flexibilität (Was wenn in 
Zukunft eben NICHT ein Zahlenwert ausreicht, sondern noch eine 
Fehlerabweichung benötigt wird?), Generische Methoden (ja, man kann auch 
mit Einheiten rechnen), Typsicherheit (Eine Temperatur ist keine 
Geschwindigkeit oder Gewicht oder Zeit...), Dokumentation (was soll ich 
100 Zeilen Kommentar verfassen wenn es ein vernünftiger Typ tut um 
auszudrücken was Sache ist).

Warum sollte ich all das verschenken (zumal der Aufwand minimal ist), 
und stattdessen darauf bauen das ich nächstes Jahr (oder mein Kollege 
morgen) noch weiß welche "ist-doch-alles-klar"-Annahmen ich getroffen 
habe.

Ich habe ja oben schon ein Beispiel verlinkt wo es konkret um Messwerte 
geht, mit denen man auch rechnen kann, und die sogar den Messfehler 
berücksichtigen.

Mark Brandis schrieb:
> Rechnen wird man alles in der gleichen, vorher festgelegten Skalierung,
> weil es anders wenig sinnvoll wäre

Auch das muss nicht sein (und ist eher einschränkend) da die zu 
verwendende Genauigkeit ggf. einstellbar oder sogar dynamisch ist. Man 
sollte sich auch nicht zu arg an den Berechnungen festkrallen, diese 
sind in den meisten Programmen nicht der Hauptbestandteil oder gerade 
dort eher generischer Natur.

Ansonsten wird hier immer schön argumentiert das es "keinen Vernünftigen 
Grund" für irgendwas gäbe, Argumente hört man leider keine.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Läubi .. schrieb:
> Ansonsten wird hier immer schön argumentiert das es "keinen Vernünftigen
> Grund" für irgendwas gäbe, Argumente hört man leider keine.

Ich denke mal das liegt einfach daran, dass viele Entwickler dafür weder 
im Studium noch im Berufsleben jemals ein Beispiel gesehen haben. Das 
heißt nicht, dass es keines gibt. Wenn es eines gibt, dann zeig doch 
bitte mal konkreten Code. Auszugsweise und beispielhaft reicht.

von Markus (Gast)


Lesenswert?

Mark Brandis schrieb:
> Ich denke mal das liegt einfach daran, dass viele Entwickler dafür weder
> im Studium noch im Berufsleben jemals ein Beispiel gesehen haben.

Das heißt aber auch nicht, dass es nicht sinnvoll ist, nur weil viele es 
nicht schaffen, sinnvolle Konzepte umzusetzen und lieber "business as 
usual" betreiben, weil wir das ja immer schon so gemacht haben.

Domainspezifische Klassen wie Temperatur, Masse, ... haben den Vorteil, 
dass man damit typsicheren Code schreibt. Jeden Fehler, den der Compiler 
findet, führt nicht zu einem Laufzeitfehler beim Kunden. Wobei das bei 
"Bastelprojekten" natürlich irrelevant ist.

Grüße
Markus

von Georg (Gast)


Lesenswert?

Läubi .. schrieb:
> Ansonsten wird hier immer schön argumentiert das es "keinen Vernünftigen
> Grund" für irgendwas gäbe, Argumente hört man leider keine.

Dass es völlig unsinniger Aufwand ist, bei einer Leiterplatte mit 20000 
Bohrungen zu jeder einzelnen Bohrung ein Objekt zu speichern statt 
einfach die X/Y-Koordinaten, ist für dich also kein Argument? 40000 mal 
die überflüssige Information, dass die Koordinaten in nm sind? Sowas ist 
bloss gut, um damit anzugeben, aber Lichtjahre von der Praxis entfernt.

Natürlich ist meine Meinung für dich völlig irrelevant, aber 
komischerweise arbeiten reale CAD-Systeme so, ganz ohne mich gefragt zu 
haben. Wahrscheinlich haben sie einfach den natürlich unverzeihlichen 
Fehler gemacht, DICH nicht zu fragen. Allerdings müssten wir dann wohl 
immer noch auf CAD-Systeme warten, die auf einem normalen PC laufen.

Georg

von Markus (Gast)


Lesenswert?

Georg schrieb:
> 40000 mal
> die überflüssige Information, dass die Koordinaten in nm sind?

Offensichtlich fehlt es Dir an der nötigen Abstraktionsfähigkeit. Wo 
steht denn geschrieben, dass man beim Modellieren einer entsprechenden 
Klasse immer eine (konstante) Einheit mit ablegt. Jeder (halbwegs) 
vernünftige Entwickler käme wohl von alleine auf die Idee, dass diese 
Information redundant sein könnte und deshalb einfach implizit im 
Klassendesign enthalten ist.

Und ganz ehlich: 40000 Objekte? Lächerlich! Wir sind heute nicht mehr in 
den Zeiten von C64 und Co., wo man mit jedem Bit rumgeizt (zumindest 
solange man sich nicht im embedded Bereich bewegt). Speicherplatz sparen 
ist sicherlich ganz nett, aber "Optimierungen" bringt man da an, wo es 
anfängt eng zu werden. Wesentlich wichtiger ist eine saubere 
Modellierung, sei es objektorientiert, prozedural oder sonst irgendwie.

Grüße
Markus

von Mark B. (markbrandis)


Lesenswert?

Markus schrieb:
> Domainspezifische Klassen wie Temperatur, Masse, ... haben den Vorteil,
> dass man damit typsicheren Code schreibt.

Markus schrieb:
> Wesentlich wichtiger ist eine saubere
> Modellierung, sei es objektorientiert, prozedural oder sonst irgendwie.

Schon recht. Nur wenn ich prozedural in C programmiere, habe ich halt 
keine Klassen. Viele Embedded-Projekte zur Steuerung von Maschinen, 
Anlagen, Fahrzeugen etc. sind nun mal in C geschrieben. Da gibt es dann 
halt keinen Prozesswert "Temperatur", der von einer Basisklasse 
"Messwert" abgeleitet ist.

von Kolllege (Gast)


Lesenswert?

Georg schrieb:
> Dass es völlig unsinniger Aufwand ist, bei einer Leiterplatte mit 20000
> Bohrungen zu jeder einzelnen Bohrung ein Objekt zu speichern statt
> einfach die X/Y-Koordinaten, ist für dich also kein Argument? 40000 mal
> die überflüssige Information, dass die Koordinaten in nm sind? Sowas ist
> bloss gut, um damit anzugeben, aber Lichtjahre von der Praxis entfernt.

Mein 3 Jahre altes "Smartphone" hat einen Duo Core Prozessor mit mind. 
1GHz Takt, dazu 16GiB RAM.
40000 Referenzen auf ein Immutable Objekt sind da gar kein Problem oder 
Faktor.
Was war nochmal mit der "Premature Optimization", diesem Spruch aus den 
70'er Jahren? ;)

von Georg (Gast)


Lesenswert?

Markus schrieb:
> Wo
> steht denn geschrieben, dass man beim Modellieren einer entsprechenden
> Klasse immer eine (konstante) Einheit mit ablegt

Das hat Läubi höchstselbst als der Weisheit letzten Schluss und als 
zwingenden Grund für eine Klasse propagiert:

Läubi .. schrieb:
> Eine Geschwindigkeit hat einen Numerischen Wert und eine Einheit

Aber wie schon Adenauer (oder wars Strauss) sagte, was geht mich mein 
dummes Geschwätz von vorgestern an.

Georg

von Jan H. (j_hansen)


Lesenswert?

Kolllege schrieb:
> Mein 3 Jahre altes "Smartphone" hat einen Duo Core Prozessor mit mind.
> 1GHz Takt, dazu 16GiB RAM.

Beim RAM hast du dich wahrscheinlich um den Faktor 16 vertan. Sollte 
aber trotzdem kein Problem sein.

von Markus (Gast)


Lesenswert?

Georg schrieb:
> Das hat Läubi höchstselbst als der Weisheit letzten Schluss und als
> zwingenden Grund für eine Klasse propagiert:
>
> Läubi .. schrieb:
>> Eine Geschwindigkeit hat einen Numerischen Wert und eine Einheit

Er hat aber NICHT geschrieben, dass jedes Objekt die Einheit 
mitschleifen muss, oder? Das ist nämlich ausschließlich Deine 
Interpretation. ;-) Seine Aussage läßt durchaus zu, dass die 
Geschwindigkeits- oder auch die Temperaturklasse die Einheit implizit 
enthält.

Grüße
Markus

von Mark B. (markbrandis)


Lesenswert?

Markus schrieb:
> Er hat aber NICHT geschrieben, dass jedes Objekt die Einheit
> mitschleifen muss, oder? Das ist nämlich ausschließlich Deine
> Interpretation. ;-) Seine Aussage läßt durchaus zu, dass die
> Geschwindigkeits- oder auch die Temperaturklasse die Einheit implizit
> enthält.

Was ist dann der Unterschied zu einer Variablen? Wenn ich Variablen zum 
Beispiel so benenne:

Battery_voltage
Vehicle_velocity
Converter_temperature

dann dürfte wohl klar sein, dass die Einheiten nicht Sekunde, Ampere und 
Watt sind.

von Fred (Gast)


Lesenswert?

Die statische Typprüfung durch den Compiler.

War das eine Fangfrage?

von Kollege (Gast)


Lesenswert?

Jan Hansen schrieb:
> Beim RAM hast du dich wahrscheinlich um den Faktor 16 vertan. Sollte
> aber trotzdem kein Problem sein.

Tatsache, meinte natürlich die SD Karte mit 16GiB, Ram hat es "nur" 
1GiB, ist ja auch schon "alt" ;)

Ansonsten finde ich es etwas schwer pro oder contra zu argumentieren 
wenn man den Kontext nicht kennt.

OOP auf einem Mikrocontroller?
Nun, der MC muss schon recht groß sein..


Assembler auf einem x86 um ein CRM zu implementieren?
Nun, da muss jemandem recht langweilig sein um so ein Unterfangen zu 
starten..

"Einheiten", mit oder ohne?
Je nachdem.. in OOP Sprachen würde ich eher mit "Ja" stimmen, als 
Immutable implementieren (in Java gar als Enum), dann reicht ein 
einziges Einheiten Objekt pro konkreter Einheit.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ich habe spaßeshalber mal die Formel für den freien Fall

dimensionssicher in C++ unter Verwendung der Boost.Units-Bibliothek
programmiert:
1
#include <iostream>
2
#include <boost/units/systems/si/io.hpp>
3
#include <boost/units/cmath.hpp>
4
5
using namespace std;
6
using namespace boost::units;
7
using namespace boost::units::si;
8
9
int main(void) {
10
  quantity<length>        fallhoehe;
11
  quantity<acceleration>  erdbeschleunigung;
12
  quantity<velocity>      geschwindigkeit;
13
14
  fallhoehe         = 3.00 * meter;
15
  erdbeschleunigung = 9.81 * meter / second / second;
16
17
  geschwindigkeit   = sqrt(2.0 * fallhoehe * erdbeschleunigung);
18
19
  cout << "Fallhöhe          = " << fallhoehe         << endl;
20
  cout << "Erdbeschleunigung = " << erdbeschleunigung << endl;
21
  cout << "Geschwindigkeit   = " << geschwindigkeit   << endl;
22
23
  return 0;
24
}

Ausgabe:
1
Fallhöhe          = 3 m
2
Erdbeschleunigung = 9.81 m s^-2
3
Geschwindigkeit   = 7.67203 m s^-1

Ändert man die Zeile
1
  geschwindigkeit   = sqrt(2.0 * fallhoehe * erdbeschleunigung);

in
1
  geschwindigkeit   = sqrt(2.0 * fallhoehe / erdbeschleunigung);

oder
1
  geschwindigkeit   = 2.0 * fallhoehe * erdbeschleunigung;

meckert der Compiler (wenngleich die Fehlermeldung schon etwas länglich
und nicht sehr aufschlussreich ist). Auf jeden Fall lassen sich damit
aber einige Fehler zur Compilezeit aufdecken, die ansonsten – wenn
überhaupt – erst zur Laufzeit zutage treten würden. Da die Überprüfung
komplett zur Compilezeit erfolgt, beinhalten die drei verwendeten
Variablen keinerlei Information über Größe, Dimension oder Einheit. Jede
von ihnen ist nur so groß wie der zugrundeliegende numerische Datentyp
(in diesem Fall double). Der Speicherverbrauch kann also kein Argument
gegen den Einsatz dieser Bibliothek sein.

Insofern ist die Boost.Units schon eine sehr feine Sache.

Das Ganze geht aber nur deswegen so leicht von der Hand, weil die Boost
alle dazu benötigten Hilfsmittel bereits fertig zur Verfügung stellt.

Würde man hingegen, wie hier von einigen propagiert, eigene Klassen
für Weg, Geschwindigkeit und Beschleunigung schreiben, wäre das selbst
in diesem primitiven Beispiel schon mit recht hohem Aufwand verbunden.
In Java, das kein Operator-Overloading kennt, würde die obige Formel
zudem ziemlich unleserlich werden.

Ich kann mir deswegen kaum vorstellen, dass sich jemand in realen
Anwendungen tatsächlich diese Mühe macht. Selbst fertige Bibliotheken,
wie die Boost.Units oder die org.osgi.util.measurement, die die
dimensionssichere Programmierung mit wenig Zusatzaufwand erlauben
würden, scheinen von von den wenigsten Programmierern genutzt zu werden.
Stattdessen werden in geschätzten 99,9% der Fälle für physikalische
Größen ganz klassisch dimensionslose Doubles ohne jegliche
Überprüfungsmöglichkeit durch den Compiler oder das Laufzeitsystem
verwendet.

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

>Insofern ist die Boost.Units schon eine sehr feine Sache.
Danke für den Hinweis.

Yalu X. schrieb:
> Selbst fertige Bibliotheken,
> wie die Boost.Units [...] scheinen von von den wenigsten Programmierern genutzt 
zu werden.

könnte an

> wenngleich die Fehlermeldung schon etwas länglich
> und nicht sehr aufschlussreich ist

liegen. Ohne zwingenden Grund will sich niemand der 
Templatefehlermeldungshölle ausliefern. In der Zeit, die man braucht, um 
aus dem ganz simplen Beispiel im Anhang -- Dein Beispiel geändert auf 
das falsche v=sqrt(2*g)*h -- herauszufinden, dass irgendein Fehler in 
Zeile 17 ist, hat man schon einen Unittest geschrieben.

von Tom (Gast)


Lesenswert?

Tom schrieb:
> Beispiel im Anhang -- Dein Beispiel geändert
Nachtrag: Der Anhang ist für einen anderen Fehler als beschrieben, die 
Meldung sieht aber ziemlich gleich aus: 12kB Müll für "In Zeile 17 
passen die Einheiten nicht."

von A. H. (ah8)


Lesenswert?

Tom schrieb:
> Tom schrieb:
>> Beispiel im Anhang -- Dein Beispiel geändert
> Nachtrag: Der Anhang ist für einen anderen Fehler als beschrieben, die
> Meldung sieht aber ziemlich gleich aus: 12kB Müll für "In Zeile 17
> passen die Einheiten nicht."

Zugegeben, lesbar ist das nicht. Aber wenigstens merke ich, dass in 
Zeile 17 ein Fehler steckt, und zwar schon während des Compilierens und 
nicht erst, wenn die millionenschwere Raumsonde den halben Weg zum Mars 
bereits hinter sich hat...

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Stattdessen werden in geschätzten 99,9% der Fälle für physikalische
> Größen ganz klassisch dimensionslose Doubles ohne jegliche
> Überprüfungsmöglichkeit durch den Compiler oder das Laufzeitsystem
> verwendet.

Ich kenne da aus der beruflichen Praxis eher Integer (Stichwort 
Festkommaarithmetik) als Gleitkommazahlen, aber der Grundaussage stimme 
ich zu.

Das wird sich im übrigen genau dann ändern, sobald ein solches Feature 
komfortabel zu benutzen ist und man nicht kryptischen Fehlermeldungen 
hinterherjagen muss. Solange wird es nämlich kaum jemand freiwillig 
nutzen wollen. Programmierer sind so. ;-)

Ach ja, und der zweite Grund dafür, dass das kaum jemand macht ist dass 
das Projektmanagement kein Geld dafür herausrückt. Niemand wird 
Hunderttausende Zeilen an bestehendem und funktionierendem Code mal eben 
verboostisieren.

Wenn man etwas von Grund auf neu entwickeln würde, dann wäre das schon 
eine gute Sache. Aber wie oft entwickelt man in einem realen 
Industrieprojekt die Dinge von Grund auf neu? Ganz genau. Meistens 
arbeitet man ja doch an etwas bereits Bestehendem und baut eine neue 
Funktionalität ein.

A. H. schrieb:
> Zugegeben, lesbar ist das nicht. Aber wenigstens merke ich, dass in
> Zeile 17 ein Fehler steckt, und zwar schon während des Compilierens und
> nicht erst, wenn die millionenschwere Raumsonde den halben Weg zum Mars
> bereits hinter sich hat...

Dazwischen sollten freilich noch ein paar Tests liegen. Wäre auch zu 
schön, wenn ein fehlerfrei kompilierendes Programm auch ein fehlerfreies 
wäre.

: Bearbeitet durch User
von A. H. (ah8)


Lesenswert?

Mark Brandis schrieb:

> Dazwischen sollten freilich noch ein paar Tests liegen. Wäre auch zu
> schön, wenn ein fehlerfrei kompilierendes Programm auch ein fehlerfreies
> wäre.

Stimmt natürlich. Mindestens genauso schön wäre es aber auch, wenn eine 
(vermeintlich) fehlerfrei getestetes Programm tatsächlich fehlerfrei 
wäre. Tests können die Fehlerfreiheit eine Programms bekanntlich auch 
nicht beweisen.

Übrigens, wer immer noch glaubt, Einheiten seien überflüssiger 
Schnickschnack, der lese zum Beispiel mal hier nach:

http://de.wikipedia.org/wiki/Mars_Climate_Orbiter

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark Brandis schrieb:
> Das wird sich im übrigen genau dann ändern, sobald ein solches Feature
> komfortabel zu benutzen ist und man nicht kryptischen Fehlermeldungen
> hinterherjagen muss. Solange wird es nämlich kaum jemand freiwillig
> nutzen wollen. Programmierer sind so. ;-)

Ist es nicht eher so, dass kaum jemand die kryptischen Fehlermeldungen
zu Gesicht bekommen hat, weil er sich die Boost.Units-Bibliothek gar
nicht erst angeschaut hat? ;-)

> Ach ja, und der zweite Grund dafür, dass das kaum jemand macht ist dass
> das Projektmanagement kein Geld dafür herausrückt. Niemand wird
> Hunderttausende Zeilen an bestehendem und funktionierendem Code mal eben
> verboostisieren.

Man muss bestehenden und funktionierenden Code nicht nachträglich
verboostisieren. Da der Code ja schon getestet ist, sollte er keine
groben Fehler mehr enthalten. Deswegen ist es ausreichend, in seinen
Schnittstellen nach außen dimensionsbehaftete Typen zu verwenden.


Noch etwas zu den kryptischen Fehlermeldungen:

F# unterstützt Maßeinheiten schon in der Kernsprache, was dem Compiler
ermöglicht, wesentlich aussagekräftigere Fehlermeldungen zu generieren.

Hier ist das obige Beispiel in F#:
1
[<Measure>] type m
2
[<Measure>] type s
3
4
let fallhoehe         = 3.00<m>
5
let erdbeschleunigung = 9.81<m/s^2>
6
7
let geschwindigkeit:float<m/s> = sqrt (2.0 * fallhoehe * erdbeschleunigung)
8
9
System.Console.WriteLine ("Fallhöhe          = {0} m", fallhoehe)
10
System.Console.WriteLine ("Erdbeschleunigung = {0} m/s^2", erdbeschleunigung)
11
System.Console.WriteLine ("Geschwindigkeit   = {0} m/s", geschwindigkeit)

In Zeile 7 wird geschwindigkeit explizit als float<m/s> deklariert,
wodurch der Compiler mögliche Dimensionsfehler im Ausdruck rechts des
Gleichheitszeichens erkennen kann.

Ändert man diese Zeile in
1
let geschwindigkeit:float<m/s> = sqrt (2.0 * fallhoehe / erdbeschleunigung)

meldet der Compiler
1
test.fs(7,58): error FS0001: The unit of measure 'm/s' does not match the unit of measure 's'

was ganz klar auf die Fehlerursache hinweist.

Es ist schade, dass nur die allerwenigsten Programmiersprachen von Hause
aus über solche Features verfügen. Außer in F# habe ich das nur noch in
Fortress gesehen, dessen Entwicklung aber leider vor ein paar Jahren
eingestellt worden zu sein scheint.

von Mark B. (markbrandis)


Lesenswert?

A. H. schrieb:
> Übrigens, wer immer noch glaubt, Einheiten seien überflüssiger
> Schnickschnack, der lese zum Beispiel mal hier nach:
>
> http://de.wikipedia.org/wiki/Mars_Climate_Orbiter

War das nicht im Pflichtenheft drin gestanden, dass man mit den 
richtigen SI-Einheiten rechnen muss und nicht mit dem Ami-Quatsch? ;-)

von Georg (Gast)


Lesenswert?

Mark Brandis schrieb:
> War das nicht im Pflichtenheft drin gestanden, dass man mit den
> richtigen SI-Einheiten rechnen muss und nicht mit dem Ami-Quatsch? ;-)

Die Amerikaner können sich einfach nicht vorstellen, dass es ausserhalb 
ihres Landes auch andere Masseinheiten gibt. Dem kann man aber mit OO 
auch nicht beikommen, denn dazu müsste man dort einen Tankinhalt ja mit 
x Gallonen definieren, wofür ein US-Ingenieur aber garkeinen Grund 
sieht, weil man das ja immer in Gallonen misst. Das ist wie beim 
ASCII-Code: mehr Buchstaben als A..Z braucht niemand. Die spinnen die 
Europäer mit ihren Umlauten.

Georg

von Georg (Gast)


Lesenswert?

A. H. schrieb:
> der lese zum Beispiel mal hier nach:
>
> http://de.wikipedia.org/wiki/Mars_Climate_Orbiter

Nachtrag: wenn erst das TTIP-Abkommen in Kraft ist, verklagt man die 
Europäer einfach auf Schadensersatz wegen Verwendung der SI-Einheiten.

Georg

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.