qualitativ hochwertiger Programmcode...
-
Shade Of Mine schrieb:
shoat schrieb:
(Vielleicht bekomme ich ja ein kleines Quellcode-Fragment im Bezug auf Mobile::Richtung? Nur, wenn Du Zeit und Lust hast!!!)
ein enum ist nur eine aufzaehlung.
ein enum ist ganz simpel:natuerlich muessen die zahlen stimmn (und ich bin jetzt zufaul mir den code anzusehen um die richtigen zahlen herauszulesen. aber das prinzip sollte klar sein
Danke für die Hilfe! Ich hatte mir schon sowas gedacht. In Java würde ich mir eine eigene Klasse schreiben, sowas wie:
public class Richtung { public final static NORDWESTEN = 0 ; public final static NORDEN = 1 ; ... }
Nochmal vielen Dank!
Wenn ich aber diese Richungsangaben nur einmal für das Mobile::go() benötige, dann muss man sich die Frage gefallen lassen, ob sich der Aufwand überhaupt mit dem enum überhaupt lohnt und nicht ein kurzer Kommentar die effektivere Lösung wäre.
Ciao
shoat
-
Daniel E. schrieb:
Liest diese Schnittstellenbeschreibung wirklich jemand?
Als reiner User eines Codes (Lib, etc.) lese immer zuerst die Schnittstellenbeschreibung. Bei vielen Libs hat man ja oft auch nicht mal die Wahl (z. B. bei den JDK's von Sun ).
Wie ich schon sagte, wenn ich den Code Warten / Prüfen / Weiterentwickeln muss bzw. will, dann sieht die Sache natürlich ganz anders aus!
Ciao
shoat
-
Helium schrieb:
Nachdem Markus mit seinem Zitat alles erklärt hat kann ich wohl nichtmehr viel beitragen.
Danke für das Beispiel! Es hat mir die Sache ganze nochmal verdeutlicht! Ich glaube mir ist jetzt klar, was damit gemeint ist! Ich finde die Sache sehr interessant. Mal sehen, wie ich das ganze in meine Arbeit integriere. Ich finde diesen Aspekt auf jeden Fall sehr hilfreich!
Helium schrieb:
Da du nicht nach Unit-Tests gefragt hast scheinst du dazu genug Material zu haben. Sowas wie Test-Driven-Design.
Den Ausdruck Test-Driven-Design habe ich zwar noch nicht gehört. Aber Du hast Recht. Ich habe vorerst recht viel Material. JUnit oder ein vergleichbares Opensource-Tool soll ein zentraler Bestandteil, des aufzubauenden Testframeworks, werden!
Viele Grüße!
Ciao
shoat
-
Puh! Das geht ja so schnell, da kommt man ja kaum mit dem Lesen nach!
Schnittstellenbeschreibungen:
Ich finde, man sollte die Signatur einer Funktion als Teil dieser Beschreibung ansehen. Und es ist der wichtigere Teil! Ich habe schon eine Million Kommentare gesehen, die gar nicht mehr zu der Funktion paßten, zu der sie gehörten. Klar, Schlamperei, aber damit muß man rechnen. Deshalb gilt für mich die goldene Regel, alles als Code zu schreiben, was man als Code schreiben kann, und Kommentare nur als zweite, nachrangige Instanz für Dokumentation zu sehen. Das gilt natürlich nicht nur für die Beschreibung einer Funktion, sondern auch für den Code innerhalb von Funktionen.Den Unterschied (von shoat) zwischen Usern der Funktion und denen, die sie warten müssen kann ich eigentlich nicht nachvollziehen - jedenfalls nicht in diesem Kontext. Natürlich, letztere müssen sich die Innereien der Funktion ansehen, um z.B. einen Fehler zu finden. Aber das hat doch mit der Schnittstellenbeschreibung höchstens am Rande zu tun. Mir geht es darum Kommentare zugunsten des Codes in den Hintergrund zu rücken. Das ist für alle Entwickler, die damit umgehen müssen von Vorteil.
enum:
Was das ist, wurde ja schon geklärt. Aber gibt es die in Java wirklich nicht?!!! Und ja, selbst wenn man hierzu eine eigene Klasse definieren müßte, fände ich den Aufwand trotzdem nicht zu hoch.class Mobile { enum Richtung { nord, nordost, ost, suedost, // usw... }; void go(Richtung richtung) throw(); };
Was bleibt da noch für die Schnittstellenbeschreibung von go() übrig?! (Ob der Name der Methode gut gewählt ist, müßte sich wohl erst im Kontext klären.)
Stefan.
-
DStefan schrieb:
Deshalb gilt für mich die goldene Regel, alles als Code zu schreiben, was man als Code schreiben kann, und Kommentare nur als zweite, nachrangige Instanz für Dokumentation zu sehen. Das gilt natürlich nicht nur für die Beschreibung einer Funktion, sondern auch für den Code innerhalb von Funktionen.
Du hast vollkommem recht, der Code muss so sprechend, als irgendmöglich gestaltet werden. Alle Kommentare innerhalb der Funktion (Klasse) können bestimmt recht kurz gehalten werden.
DStefan schrieb:
Den Unterschied (von shoat) zwischen Usern der Funktion und denen, die sie warten müssen kann ich eigentlich nicht nachvollziehen - jedenfalls nicht in diesem Kontext.
Ich habe dabei von Kommentaren im allgemeine geredet, wenn ich mißverstänlich ausgedrückt habe, dann tut es mir Leid.
Auf jeden Fall möchte ich an der Unterscheidung festhalten. Kommentare an unterschiedlichen Stellen haben verschiedene Zielgruppen, damit müssen auch auch verschieden gestaltet werden. Danke, dass ihr mich darauf aufmerksam gemacht habt! Allerdings muss ich mich verbessern:
DStefan schrieb:
Mir geht es darum Kommentare zugunsten des Codes in den Hintergrund zu rücken. Das ist für alle Entwickler, die damit umgehen müssen von Vorteil.
Soweit hast Du vollkommen recht. Alle Kommentare dürfen auf zugunsten des Codes in den Hintergrund rücken. Wirklich alle! Diese Aussage kann ich wirklich gut akzeptieren. Jedenfalls, solange darunter die Verständlichkeit des Codes für Kenner nicht leidet!
Nur auf eines möchte ich beharren. Schnittstellenbeschreibungen, die nach außen gehen (public!), die also auch der User / Laie verstehen muss, sollten zusätzlich sehr ausführlich, meint newbie-tauglich gehalten werden.
(In der Tat sind, dass auch die Schnittstellen, an denen unter Java javadoc ansetzt, auch, wenn ich es bisher nie so empfunden habe.)
Können wir uns darauf einigen?
Wenn mich jemand davon abbringen will, dann muss er sich schon gute Argumente einfallen lassen!
Viele Grüße und v. a. vielen Dank!
Ciao
shoat
-
shoat schrieb:
Du hast wirklich vollkommen recht, dass es die obere Lösung vollkommener Schachsinn ist. Und natürlich ist die untere Lösung viel besser. Aber in der Form kann man sie meiner Meinung nach unmöglich belassen. So würde ich sie idealweise einstellen.
public class Mobile... /** * Versetzt das Mobile in die angegebene "richtung". * @param richtung Gibt die Richtung an. Dabei bedeutet richtung%9 * gleich 0 linksunten, 1 unten, 2 rechtsunten, * 3 links, ... */
ähm. wolltest du mir jetzt zeigen, daß ein wechsel nach java besser ist? oder daß man mehr kommentare machen soll?
übrigens: ein wort sagt weniger als 1e-3 bilder.
/* richtungen: 012 345 678 */
[quote="shoat"]
public void go (int richtung) { this.posX += richtung%3-1 ; this.posY += richtung/3-1 ; } }
Genau so finde ich es am besten. Damit schneidet die Funktion (denke ich?) auch bei Metriken gut ab und nichts von Deiner guten Lösung geht verloren.[/java]
"am besten" ist eine so fette beschreibung...
nee, offensichlich ist schonmal das hier besser:/*evtl private:*/ void go(Vector richtung) { pos+=richtung; } public: void go(enum Richtungsname richtungsname) { pos+=richtungsnameToRichtung[richtungsname]; } //enum und [] nur zur verdeutlichung.
aber am besten ist das noch nicht.
double* find(double toFind,double* arr,int size) { for(int i=0;i<size;++i) if(arr[i]==toFind) return &arr[i]; return 0; }
Guter Algorithmus, aber auch zu dieser Funktion (zumindest, wenn sie public ist) gehört meinesachtens eine Schnittstellenbeschreibung!
echt?
Warum? Ganz einfach. Wenn Dritte Deinen Code nutzen sollen, dann fällt ihnen dies viel leichter, wenn die nutzbaren Schnittstellen verständlich beschrieben sind. I. d. R. dauert es viel länger, wenn man erst den Quell-Code anschauen und verstehen muss.
aha. I.d.R. also. aber obige funktion ist doch a.d.R., oder? was ist, wenn man so geil programmiert, daß 95% der funktionen in diesem sinne a.d.R sind? abgesehen davon, daß dann a.d.R d.R ist, wodurch etwas unsinnigerweise i.d.R a.d.R ist, wäre es i.d.R nicht nutwendig, die schnittstelle nochmal extra zu beschreiben. natürlich beschreibt man die 5% a.d.R-Funktionen. also man beschreibt das, was nicht offensichtlich ist. i.d.R kann jeder ein ++x lesen und man schreint nicht "//erhöht x" hin. wozu dir find(...) oder die go(...) noch spezifizieren. oder fine mal einen, der bei "void go(Vector richtung)" oder "void go(enum Richtungsname richtungsname)" nicht sofort weiß, was die methode macht. (falls du ihn findest, leih ihm netterweise ein anfängerbuch.)
-
shoat schrieb:
Nur auf eines möchte ich beharren. Schnittstellen, die nach außen gehen (public!), die also auch der User / Laie verstehen muss, sollten zusätzlich sehr ausführlich, meint newbie-tauglich gehalten werden.
(In der Tat sind, dass auch die Schnittstellen, an denen unter Java javadoc ansetzt, auch, wenn ich es bisher nie so empfunden habe.)
Können wir uns darauf einigen?
Nein, ich finde das weder notwendig noch wünschenswert!
Code, der Newbie- oder gar Laien-tauglich ist, ist normalerweise alles andere als qualitativ hochwertig! Dasselbe gilt (vielleicht sogar in verstärktem Maße) für Kommentare bzw. Schnittstellenbeschreibungen. Wie soll ich mir Code vorstellen, der dieser Anforderung genügt, was soll ich voraussetzen können und was nicht?! Das ist doch bei diesen Zielgruppen kaum zu entscheiden. Ich müßte so ziemlich alles erklären, was schon im Code zu sehen ist, denn ein Newbie (oder gar ein Laie) kennt es möglicherweise nicht.
Qualitativ hochwertiger Code muß voraussetzen können, daß der Entwickler, der damit zu tun hat, sein Geschäft beherrscht. Das bedeutet nicht nur, daß er die Sprachmittel und Standard-Bibliotheken erschöpfend kennt, sondern auch Dinge, wie Design Patterns, grundlegende Algorithmen usw., die also mit der Programmiersprache nichts zu tun haben. Und selbst Kenntnisse bezüglich des Fachgebiets, für das die Software geschrieben ist, muß man voraussetzen können - zumindest grundlegende Kenntnisse.
Newbies sollten genügend Erfahrungen mit nicht produktivem Code machen, bevor sie ernsthaft zu entwickeln beginnen. Sie haben an produktivem Code nichts zu suchen! Das gilt natürlich erstrecht für Laien. In diesem Sinne ist natürlich wieder einmal XP erwähnenswert: Das Pair Programming ist, finde ich, genau das Richtige, um Newbies schnell an ihren Job heranzuführen. (Bloß schade, daß in diesem unserm Lande die Firmen anscheinend überhaupt kein Intersse an XP haben. Oder weiß jemand einen XP-Job für mich?
).
Stefan.
-
DStefan schrieb:
Im Falle von find() fehlt eine Fehlerbehandlung (arr darf nicht 0 sein).
und was passiert da? ein assert? da ist meine schutzverletzung doch gleichwertig.
bei msvc gilt: die dereferenzierung von 0 löst eine feine schutzverletzung aus, die öffnet die ide und zeigt auf die code-zeile, wo es passiert ist und man kann prima die variableninhalte und alles so inspizieren und in wenigen sekunden hat man den fehler behoben.
-
Helium schrieb:
assert(ergebnis * ergebnis == radiant);
nutzlos. das ist nur ne umformulierung des programmcodes. wirksamer ist ne testfunktion, die nur den zweck hat, die funktion zu testen.
dann passieren auch so fehler nicht, wie "assert(ergebnis * ergebnis == radiant);" statt "assert(fabs(ergebnis*ergebnis-radiant)<=42*WILLKUER);"
-
shoat schrieb:
Ich persönlich würde es trotzdem dazuschreiben, wenn es sich um public-Funktionen (s. o.) handelt.
Denn eine Schnittstellenbeschreibung sollte unbedingt immer gemacht werden!wir fragen, warum eine schn. immer gemacht werden muß. da reicht als begürndung nicht "denn eine schn. muß immer gemacht werden!!!!".
-
DStefan schrieb:
Nein, ich finde das weder notwendig noch wünschenswert!
...Deine Ausführungen bzgl. des Codes kann ich nur bestätigen.
Allerdings bleibe ich dabei, dass man die externen Schnittstellen erschöpfend beschreiben muss. D. h. die Dokumentation muss einem alles sagen, was man benötigt, um die Funktion bzw. Klasse korrekt nutzen kann. Es ist schließlich so, dass man bei einigen Libs keine Möglichkeit hat den Quellcode (abgesehen von den Prototypen natürlich) einzusehen. (Wohl aber die aus den Kommentaren entstehene Dokumentation!)
Viele Grüße
shoat
-
und nochwas aus der ganz ganz tiefen praxis:
ungutes gefühl haben bei/*richtungen 0 1 2 3 4 5 6 7 8 */
gutes gefühl haben bei
/*richtungen 7 8 9 4 5 6 1 2 3 */
das erkennt der kundige progger nämlich als das muster auf dem ziffernblock und wenn er mal die grafik bildlich braucht, weils schwieriger wird, muß er nicht blättern.
-
volkard schrieb:
shoat schrieb:
Ich persönlich würde es trotzdem dazuschreiben, wenn es sich um public-Funktionen (s. o.) handelt.
Denn eine Schnittstellenbeschreibung sollte unbedingt immer gemacht werden!wir fragen, warum eine schn. immer gemacht werden muß. da reicht als begürndung nicht "denn eine schn. muß immer gemacht werden!!!!".
Du bist nicht mehr up2date. Ich habe diese allgemeine Meinung
1. revidiert und
2. ausführlich erklärt warumSolltest ich mich irgendwo mißverständlich ausgedrückt haben. Dann sag mir ruhig Bescheid.
Vielleicht sollest Du und auch alle anderen Bedenken, dass ich weder die Erfahrung noch dass Wissen von Dir / Euch habe. Deswegen höre ich etwas, sage meine Meinung dazu und lasse mich dann belehren, oder auch nicht. Ihr seid also meine Quasi-Lehrer! (und ich der ungezogene Schüler
)
Vielen Dank für Deine Beiträge!
Ciao
shoat
-
volkard schrieb:
shoat schrieb:
public class Mobile... /** * Versetzt das Mobile in die angegebene "richtung". * @param richtung Gibt die Richtung an. Dabei bedeutet richtung%9 * gleich 0 linksunten, 1 unten, 2 rechtsunten, * 3 links, ... */
ähm. wolltest du mir jetzt zeigen, daß ein wechsel nach java besser ist? oder daß man mehr kommentare machen soll?
zweiteres
(Aber vielleicht auch ersteres. Hast Du Dich schon bei der xavo beworben?)volkard schrieb:
übrigens: ein wort sagt weniger als 1e-3 bilder.
/* richtungen: 012 345 678 */
Du hast vollkommen recht. Dieses Bild habe ich heute auch schon gemalt! Nur bin ich von einem kartesichen Koordinatensystem ausgegangen. Ich hatte mich schon gewundert, warum bei Nordwest xPos-- und yPos-- gelten soll. Ich habe etwas länger gebraucht um dahinter zu kommen, dass Du in Bildschirmkoordinaten gerechnet hast. I'm really sorry!
volkard schrieb:
"am besten" ist eine so fette beschreibung...
Mit meinem bescheiden Wissen, fand ich es so besser und es war das Beste, was mir dazu im Moment eingefallen ist. Wobei ich mich v. a. auf die Kommentierung bezogen hatte.
Natürlich ist der superlativ "am Besten" wahrscheinlich nie angebracht, genauso wenig wie es schicklich ist immer oder nie zu sagen. Es gibt bestimmt immer was besseres, also sollte man nie "am Besten" sagen. Ich wundere mich immer wieder, warum mir soetwas passiert. Selbstreded weiss ich, dass Dir sowas noch nie passiert ist...
Warum? Ganz einfach. Wenn Dritte Deinen Code nutzen sollen, dann fällt ihnen dies viel leichter, wenn die nutzbaren Schnittstellen verständlich beschrieben sind. I. d. R. dauert es viel länger, wenn man erst den Quell-Code anschauen und verstehen muss.
Ich möchte nochmals sagen, dass ich meine Meinung bzgl. der Schnittstellbeschreibung schon revidert habe.
Es ist natürlich schön dem anderen gelegentlich das Wort im Mund rumzudrehen und genau das reinzuinterpretieren, was er nicht ausdrücken wollte.
Du weißt genauso gut wie ich, dass sich alle nicht Freaks (meint Du und Deinesgleichen ausgeschlossen) bestimmt mit einer kurzen Beschreibung viel leichter täten, als mit dem reinen Quelltext. Dass ich bestimmt nicht darauf aus war, dass jemand Kommentar machen muss, wenn er x++ verwendet, weißt Du genau! Wenn jemand allerdings zum Manövrieren eines Cursors über den Bildschirm
void Mobile::go (int richtung) { int rx=richtung%3-1; int ry=richting/3-1; x+=rx; y+=ry; }
verwendet. Dann wäre es doch schon recht schön, wenn er mir einen kurzen Tip geben würde, was es eigentlich zu bedeuten hat. Oder ist es sinnvoll, wenn jeder, der den Funktion benutzen soll, erst die Formeln nachvollziehen muss? Deswegen wäre ich für einen Kommentar (Schnittstellenbeschreibung) - gerne in Form einen Bildes (s. o.) - sehr dankbar.
Ich hoffe, ich habe mich nicht schon wieder mißverständlich ausgedrückt.
Ciao
shoat
-
shoat schrieb:
Wenn jemand allerdings zum Manövrieren eines Cursors über den Bildschirm
void Mobile::go (int richtung) { int rx=richtung%3-1; int ry=richting/3-1; x+=rx; y+=ry; }
verwendet. Dann wäre es doch schon recht schön, wenn er mir einen kurzen Tip geben würde, was es eigentlich zu bedeuten hat.
ja. der schwere fehler,
void Mobile::go(int richtung)
zu schreiben, verzerrt die angelegenheit. in dieser verzerrten lage isses natürlich gut, die schnittstelle zu kommentieren.
aber das ist jetzt ein wenig wie wenn man beweist, daß goto gut ist, solange man keine destruktoren verwendet.
-
ich warte auf die metrikenbefürworter. immerhin werden die ja eingesetzt. immerhin lernt man an hochschulen, wie toll die sind.
-
volkard schrieb:
shoat schrieb:
Wenn jemand allerdings zum Manövrieren eines Cursors über den Bildschirm
void Mobile::go (int richtung) { int rx=richtung%3-1; int ry=richting/3-1; x+=rx; y+=ry; }
verwendet. Dann wäre es doch schon recht schön, wenn er mir einen kurzen Tip geben würde, was es eigentlich zu bedeuten hat.
ja. der schwere fehler,
void Mobile::go(int richtung)
zu schreiben, verzerrt die angelegenheit. in dieser verzerrten lage isses natürlich gut, die schnittstelle zu kommentieren.
aber das ist jetzt ein wenig wie wenn man beweist, daß goto gut ist, solange man keine destruktoren verwendet.... Du bist ja auf meine Argumentation gar nicht eingegangen ...
Schade, ich hatte ursprünglich gedacht, Du wolltest mir helfen.
-
Hallo Leute,
nachdem wir das Thema der Kommentare recht ausführlich behandelt haben, wäre es schön, wenn wir jetzt auch die meinen anderen Fragen behandeln könnten! Vor etwa vier Seiten habe ich gefragt:
**
Was stellt ihr persönlich sicher, dass Euer Code
- gut kommentiert/dokumentiert ist?
- gut wartbar ist?
- (möglichst) fehlerfrei ist?
- eine gute Performance besitzt?
- plattformunabhängig bzw. leicht portabel ist?
- (wenigstens teilweise) wiederverbar ist?**Für neue Ideen in all diesem Bereich wäre ich sehr dankbar! Insbesondere zu den letzten drei Punkten habe ich noch kaum Antworten bekommen! Wäre also sehr schön, wenn ihr mir da ein wenig unter die Arme greifen könntet!
Vielen Dank für die Hilfe!
Ciao
shoat
-
shoat schrieb:
... Du bist ja auf meine Argumentation gar nicht eingegangen ...
Schade, ich hatte ursprünglich gedacht, Du wolltest mir helfen.Pfüüüüü.... halt mal den Ball flach.
Vielleicht war er auch der Ansicht, es wäre offensichtlich.
shoat schrieb:
... Du bist ja auf meine Argumentation gar nicht eingegangen ...
Wenn Du als Richtung einfach einen int-Parameter reinwirfst, ohne Kommentar, dann ist klar daß der Code mit dem Modulo(3) unverständlich ist.
Denn korrekt wäre es hier gewesen eine Legende für den int-Parameter zu machen, sowas in der Art:
/*richtungen 7 8 9 4 5 6 1 2 3 */
Denn damit kann man die Berechnung verstehen, die 3 vom Modulo ergibt auf einmal ("aha, ein 3er-Block mit Richtungen") Sinn.
Oder man macht's mit einem Enum.
Und man gibt der Funktion noch den Namen "followCompassDirection" (oder sowas in der Art).
Aber go(int) ist halt recht wenig.
-
shoat schrieb:
Was stellt ihr persönlich sicher, dass Euer Code
- gut kommentiert/dokumentiert ist?
- gut wartbar ist?
- (möglichst) fehlerfrei ist?
- eine gute Performance besitzt?
- plattformunabhängig bzw. leicht portabel ist?
- (wenigstens teilweise) wiederverbar ist?Für neue Ideen in all diesem Bereich wäre ich sehr dankbar! Insbesondere zu den letzten drei Punkten habe ich noch kaum Antworten bekommen! Wäre also sehr schön, wenn ihr mir da ein wenig unter die Arme greifen könntet!
Eigentlich dachte ich, wir sprechen von diesem Thema... das steht doch alles da. Bisher war es eine interessante und lehrreiche Diskussion, der aufmerksame Zuhörer konnte einiges mitnehmen. Nun gut.
- Kommentiert/Doku: hat die Diskussion ergeben, die Masse der Leute steht er auf eindeutige Namen für Klassen, Objekte und Variablen statt Kommentaren. Für die Struktur der Klassen ist teilweise ein UML-Klassendiagramm hilfreich.
- wartbar: schlankes Design, nur genau das machen was man soll, das eigentliche Problem lösen
- fehlerfrei: schlankes Design, automatische Tests, Assertions bzw. allgemein Bereichsüberprüfungen
- Performance: erst Mal muß es laufen... optimiert wird danach, d.h. Rapid Prototypen in einigen Bereichen, Profiling, danach Optimierung kritischer Zeitfresser. Und: schlankes Design, da solche Programme oftmals effizienter sind.
- Plattformunabhängig wird in der Praxis massiv überbewertet und ist oftmals vernachlässigbar. Berücksichtigt man bei seinen Applikationen das MVC-Modell, kann man die Klassen in OS-abhängige Teile (GUI, Viewer) und Modell (ISO-C++) trennen, damit hat man ein portables funktionierendes Modell
- wiederverwendbar: wie immer: schlankes Design, das genau das macht was das Programm aus der realen Welt abbilden soll. Während der Entwicklung reduziert man dadurch Dinge auf das wesentliche, Erweiterungen können sich dann später abstützen. Ansonsten habe ich ja einen ganzen Sermon dazu geschrieben, ich verstehe nicht wieso Du denkst daß es dazu noch keine Punkte gibt.