Dies ist eine statische Kopie unseres alten Forums. Es sind keine Interaktionen möglich.
This is a static copy of our old forum. Interactions are not possible.

Neutrino

masselos

  • "Neutrino" is male

Posts: 661

Date of registration: Oct 6th 2005

Location: Hannover

Occupation: SRA Mitarbeiter

21

Wednesday, August 2nd 2006, 11:00pm

Quoted

Original von Markus

Quoted

Original von julianr
Und weils zum Thema "schöner arbeiten mit Arrays" so schön passt, auch gleich den noch hinterher: http://www.joelonsoftware.com/items/2006/08/01.html


Den merke ich mir wenn das nächste Semester losgeht und in den Analen des Forum wieder die Schreie dutzender verzweifelter ErSies wiederhallen "Warum machen wir Scheme und nicht Java". ;)


Das frage ich mich heute noch! Aber das diskutieren wir in 2Monaten mit den Ersis ;-)

dluebke

Trainee

  • "dluebke" is male

Posts: 37

Date of registration: Aug 26th 2004

22

Thursday, August 3rd 2006, 10:59am

Quoted

Original von julianr

Quoted

Original von Joachim
Allerdings legt die mehrfache Verwendung einer Methode den Schluß nahe, daß diese Methode von allgemeiner Bedeutung für die verwendete Datenstruktur ist. Von daher wäre es vielleicht besser, die Methode in eine neue Klasse auszulagern, die die verwendete Datenstruktur modelliert.


Das kann man analog über jede Art von lokaler Definition sagen - verschachtelte Klassen, lokale Konstanten usw.


Hmm, der Hauptsinn von Verschachtelungen ist es meiner Meinung nach, den Namensraum und damit die Zusicherungen an Aufrufer kleinzuhalten. Daher auch Methoden private machen, wenn es geht, weil man sie nach aussen damit nicht zusichert und einfach streichen kann etc.

Wenn eine Methode/Funktion so groß ist, dass sie zerlegt werden muss, dann ist sie halt zu groß. Und wenn ich dann hierarchisch die noch zerlege... Ich finde schon inner und nested classes recht unschön, weil man dann wirklich gute Editoren braucht. Und mit Funktionen ist das nicht anders: Um dann noch die Übersicht zu behalten, ob die in einer Funktion oder ausserhalb steht, braucht man wohl Code-Folding und visuelle Elemente. Was mich daran aber am meisten stören würde ist, dass es dann mehrere Elemente gäbe, die nicht mehr auf eine Bildschirmseite passen: In Java ist eine Klasse länger als dieses Limit, Methoden sollten es nicht sein. Wenn ich nun Unterfunktionen einführe, wären Funktionen zwangsläufig auch länger als eine Seite.

Quoted


Aber Aufgeräumtheit und minimalistische Interfaces sind ja eh was, wofür Java ganz falsch ist... Ernsthaft, muss das einer Sprache nicht peinlich sein, wenn die IDEs sich damit überbieten, welche den meisten Fließbandcode automatisch generiert? Ich musste jetzt einfach mal trollen, weil ich die Kombination aus Java und Spaß nie verstehen werde :x


Mal abgesehen von J2EE <= 1.4 (was in der 1.5/5.0er schon deutlich besser aussieht) gibt es in Java nicht mehr Fließbandcode als in anderen Sprachen auch. Ich habe auch sonst nirgendswo GUI-Builder etc. gesehen die kurze Quelltexte(!) generieren. Das beste, was ich bisher gesehen habe ist der Qt Designer, der aber auch die visuellen Informationen in XML-Dateien hält und dann daraus in einem Precompiler C++-Sourcen generiert. Aber da wird dann auch wieder viel generiert, aber wenigstens ist der Code, den man sieht und mit dem man arbeitet, sauber.
Wenn ich mich alleine an Turbo Vision in Turbo Pascal erinnere... Dagegen ist Swing ein echter Segen.

Quoted


Und weils zum Thema "schöner arbeiten mit Arrays" so schön passt, auch gleich den noch hinterher: http://www.joelonsoftware.com/items/2006/08/01.html


Hmm, der Artikel ist so ein typischer Joel-Artikel... Er "bashed" gerne rum und so durchdacht sind einige seiner Artikel leider nicht. Also erstmal gibt es keine Funktionen in objektorientierten Sprachen, sondern halt nur - welch Überraschung - Objekte (und Klassen). Das ist wohl sein Hauptproblem.

Und das, was er Functor nennt, also ein Interface mit entsprechenden Methoden, evtl. nur einer, ist eine recht schöne Variante, die ich bei weitem nicht so schlimm finde, wie er tut (vgl. Runnable, ActionListener, ...). Aber bevor wir zur Schönheit kommen, halten wir erstmal ein paar Dinge zu dem Artikel fest:
  1. Funktional macht es keinen Unterschied, ob ich eine Funktion oder ein Objekt mit definierter Methode übergebe.
  2. Ich kenne wenige Fälle, in denen ich eine Schleife wegabstrahieren musste.
  3. Sein Code ist aufgrund der Bezeichnernamen (f als Parameter ist eine Funktion, aber was soll die machen), sicherlich nicht so lesbar wie er meinte, dass der Code durch die Technik wird!
    [/list=1]

    Der Vorteil von definierten Interfaces, die übrigens auch immer sauber sein sollten (ansonsten hat der Programmierer und nicht die Sprache was falsch gemacht), ist, dass man auch etwas garantiert (bekommt), und was er dementsprechend in seinem Beispiel nicht drin hat, nämlich statische Typsicherheit. Seine Cook-Funktion kann letztendlich alles tun (f muss ja nicht kochen, Sachen einpacken o.ä.). Eigentlich dürfte sie deshalb auch nicht mehr Cook heißen sondern AlertAndCallAFunction. Und alleine daran sieht man, dass der Gute soweit wegabstrahiert hat, dass es doch sehr generisch und beliebig geworden ist. Und daher ist auch dieser Name schlecht. Zudem kann der Compiler (scheint auch eher eine interpretierte Sprache zu sein) nicht überprüfen, welchen Bedingungen die Methode (= Parameter) genügen muss. Das bedeutet erhöhten Testaufwand. Zusätzlich fällt damit auch automatisch etwas von Selbstdokumentation weg.

    Mit den Interfaces kann man in Java (oder genereller OOP) alles machen, was er vorschlägt: Inline "Funktionen" definieren (inner classes oder nested classes, auch anonym!) und abstrakte Schnittstellen definieren (die dann sogar mehr als eine Methode haben dürfen, was dann sogar noch besser ist, z.B. nicht nur mit 2 Parametern arbeiten sondern über eine Liste iterieren, dabei eine Methode aufrufen (putInPot) und zum Schluß eine andere Methode aufrufen (heat)). Zusätzlich kriegt man ein Objekt, d.h. man hat einen Zustand, den eine Funktion nicht haben kann. Das hat manchmal auch Vorteile.

    Jede Sprache und jedes Programmierkonzept hat seine Vorteile. OOP sieht jedenfalls eher so aus wie in Java und wenn man das anders haben möchte, dann muss man sich halt funktionale oder prozedurale oder noch ganz andere Sprachen suchen.

    Jede Sprache hat entsprechend ihre Vor- und Nachteile. Java ist mit den primitiven Datentypen ein wenig inkonsequent, was historisch gewachsen ist, und Signals/Slots in Qt sind z.B. ein wenig schöner als selber Observer/Listener bauen zu müssen. Aber alles in allem ist es eine runde OO-Sprache, mit der man viel machen kann und die sicherlich auch ihre Stärken hat (vom Handy bis zum Server z.B.)

    Daniel

denial

Erfahrener Schreiberling

  • "denial" is male

Posts: 394

Date of registration: Feb 18th 2003

Location: Göttingen

Occupation: Linux Coder (ex Mathe SR Inf Student)

23

Thursday, August 3rd 2006, 12:11pm

Quoted

Original von dluebke
Was mich daran aber am meisten stören würde ist, dass es dann mehrere Elemente gäbe, die nicht mehr auf eine Bildschirmseite passen: In Java ist eine Klasse länger als dieses Limit, Methoden sollten es nicht sein.
Ich bevorzuge eine Schriftgröße bei der ich bei maximiertem Fenster 28 Zeilen im Editor auf den 15" Bildschirm kriege. Und das ist definitiv nicht genug für manche Algorithmen. Denn manchmal will man auch performanten Code schreiben und nicht nur GUI Code bei dem letztendlich der Benutzer das langsamste Element ist. Auch im Quellcode von SUNs Java Klassen finden sich Methoden die deutlich länger sind.

Quoted

Ich habe auch sonst nirgendswo GUI-Builder etc. gesehen die kurze Quelltexte(!) generieren.

GUI sollte IMHO niemals in Quellcode umgesetzt werden. Der Code ist immer häßlich und sogar kompiliert noch riesengroß. Zu Atari ST Zeiten gab es .rsc Dateien, Apple hat(te?) seine Resource Forks, unter Windows gibt es Resourcen Segmente und mit libglade kann man GLADE XML Dateien durch drei Zeilen Code einbinden. Ein Vorteil ist, daß man die GUI übersetzen, oder sogar komplett umstellen kann, ohne auch nur eine Zeile des Codes anzufassen. Das einzige was ein GUI Builder an Code erzeugen darf, sind leere Stubs für die gewünschten Handler.

Ein Beispiel:
gtk-gnutella 0.96.1 hat in src/ui/gtk/gtk1 eine interface-glade.c Datei deren zweite Zeile "DO NOT EDIT THIS FILE - it is generated by Glade." lautet.
Diese Datei ist 946848 Byte groß und kompiliert auf 428426 Byte (allein das Textsegment).
Die dazugehörige .glade Datei ist gzip komprimiert (damit kann der XML Parser umgehen) 46290 Byte groß.
Libglade 0.17 ist kompiliert 98340 Byte groß.
Ok, libxml und libz kommen noch dazu, aber die könnten vom Programm sowieso gebraucht werden. Außerdem linken wir dynamisch.

  • "Joachim" is male

Posts: 2,863

Date of registration: Dec 11th 2001

Location: Hämelerwald

Occupation: Wissenschaftlicher Mitarbeiter (Forschungszentrum L3S, TU Braunschweig)

24

Thursday, August 3rd 2006, 7:38pm

Quoted

Original von denial

Quoted

Original von dluebke
Was mich daran aber am meisten stören würde ist, dass es dann mehrere Elemente gäbe, die nicht mehr auf eine Bildschirmseite passen: In Java ist eine Klasse länger als dieses Limit, Methoden sollten es nicht sein.
Ich bevorzuge eine Schriftgröße bei der ich bei maximiertem Fenster 28 Zeilen im Editor auf den 15" Bildschirm kriege. Und das ist definitiv nicht genug für manche Algorithmen.
28 Zeilen finde ich schon recht viel. Gerade bei Algorithmen, die mehr Zeilen bei der Implementierung bräuchten, bieten sich ja Zerlegungen an.

Quoted

Denn manchmal will man auch performanten Code schreiben und nicht nur GUI Code bei dem letztendlich der Benutzer das langsamste Element ist.
Die Optimierung des Code ist sowieso eine ganz andere Baustelle. Zunächst sollte meiner Meinung nach der Code auf Verständlichkeit, Wartbarkeit, Übersichtlichkeit und natürlich Korrektheit auslegt sein. Hier halte ich die Regel "höchstens eine Bildschirmseite Code pro Methode" für sinnvoll.

Erst nach diesem Schritt sollte man sich Gedanken über das "Tuning" machen (und natürlich die Änderungen gut dokumentieren!). Viele häßliche "Tuning-Tricks" lassen sich aber meiner Erfahrung nach vermeiden, wenn man zum einen weiß, wie der Compiler und die JVM den Code optimieren, und zum anderen die Wirksamkeit der Änderungen mit einem Profiler überprüft. Schneller Code ist nach meiner Erfahrung nur in den seltensten Fällen notwendigerweise langer und unübersichtlicher Code.

Im übrigen sollte auch (und gerade) GUI-Code eine hohe Qualität besitzen. Denn dieser Code beschreibt das, was der Benutzer von der Anwendung wahrnimmt.

Quoted

Auch im Quellcode von SUNs Java Klassen finden sich Methoden die deutlich länger sind.
Der Code von Sun soll auch kein Vorbild sein; und ist an vielen Stellen auch alles andere als das. Beispielsweise wurde vor einiger Zeit hier an der Uni vom KBS untersucht, inwieweit im Code der Java API von Sun die Regel "program to an interface, not an implementation" berücksichtigt wurde: das Ergebnis war, daß dies längst nicht in dem Maße der Fall ist wie es möglich wäre.
The purpose of computing is insight, not numbers.
Richard Hamming, 1962

This post has been edited 1 times, last edit by "Joachim" (Aug 3rd 2006, 7:39pm)


julianr

Erfahrener Schreiberling

Posts: 298

Date of registration: Oct 13th 2005

Location: I live in a giant bucket.

25

Friday, August 4th 2006, 12:05am

Quoted

Original von dluebke
Ich finde schon inner und nested classes recht unschön, weil man dann wirklich gute Editoren braucht. Und mit Funktionen ist das nicht anders: Um dann noch die Übersicht zu behalten, ob die in einer Funktion oder ausserhalb steht, braucht man wohl Code-Folding und visuelle Elemente.


Weiß nicht, ich finde Einrückung reicht, vielleicht bin ich Pascal-vorgeschädigt.
Du gehst aber anscheinend davon aus, dass man das nur verwenden würde, um riesige Algorithmen aufzuteilen. Sehe ich anders, auch in einer Funktion, die keinen Bildschirm füllt, will man vllt einfach drei Schritte, die man an wenigen verschiedenen Stellen auf irgendeine Variable anwendet, kurzerhand auslagern - einfach um Redundanz auf dem Minimum zu halten. Und vielleicht sieht die Ursprungsfunktion von kleinen Wiederholungen befreit auf einmal ja auch sehr kompakt und eindeutig aus, wenn die innere Funktion auch noch gut benannt wurde? ;)

Quoted


Mal abgesehen von J2EE <= 1.4 (was in der 1.5/5.0er schon deutlich besser aussieht) gibt es in Java nicht mehr Fließbandcode als in anderen Sprachen auch.


Bei GUIs sehe ich es so, dass man die einfach nicht als Quelltext speichern sollte. Ich dachte eher an triviale Sachen wie Getter/Setter (pfui von vornherein ;) ).
Oder eben den Code, den man braucht, um den Mangel an Lambda-Ausdrücken auszugleichen - wobei einem das die IDE ja nicht einmal abnimmt, afaik.

Quoted


Also erstmal gibt es keine Funktionen in objektorientierten Sprachen, sondern halt nur - welch Überraschung - Objekte (und Klassen). Das ist wohl sein Hauptproblem.


Sein (und mein) Hauptproblem ist wohl, dass Java krampfhaft einseitig objektorientiert ist - und der Horizont der Sprache da auch endet.

Quoted


  • Funktional macht es keinen Unterschied, ob ich eine Funktion oder ein Objekt mit definierter Methode übergebe.
  • Ich kenne wenige Fälle, in denen ich eine Schleife wegabstrahieren musste.



Es macht auch keinen Unterschied, ob man nun Objekte verwendet, oder structs und viele globale Funktionen mit einem this-Zeiger. Lambdas in C# sind auch nur platter syntaktischer Zucker, so wie Objekte in vielen Sprachen. Letztendlich kann man alles nachbauen. Aber wenn eine Sprache einen einfach schreiben lässt, was man denkt, dann hat das nunmal nur Vorteile. Hallo Ruby:

Source code

1
2
Person heinz = personen.find { ?|p| p.name == "Heinz" }
personen.sort_by { |p| p.schuhgröße }


Für das erste würde man in vielen Sprachen eine for-Schleife nehmen - wie für fast alles, weswegen man erstmal genau hingucken muss, was eigentlich passiert. Für das zweite eine Funktion, der man irgendeine Art von Functor übergibt.
Niemand zwingt einen dazu, die zu Grunde liegenden Schleifen (oder was auch immer) wegzuabstrahieren, aber an Les- und Wartbarkeit macht man da imho einen ganz schönen Gewinn.

Quoted


Eigentlich dürfte sie deshalb auch nicht mehr Cook heißen sondern AlertAndCallAFunction. Und alleine daran sieht man, dass der Gute soweit wegabstrahiert hat, dass es doch sehr generisch und beliebig geworden ist.


Schon, aber andersrum finde ich es oft ziemlich einschränkend, dass man sich als Autor einer Klasse in Java schon im Voraus Gedanken machen muss, was man damit vielleicht mal alles machen will (konkret, welche Interfaces man implementiert). In Fragen der Typsicherheit fehlt imho vielen (allen?) Sprachen der Mittelweg.

Quoted


...die dann sogar mehr als eine Methode haben dürfen, was dann sogar noch besser ist, z.B. nicht nur mit 2 Parametern arbeiten sondern über eine Liste iterieren, dabei eine Methode aufrufen (putInPot) und zum Schluß eine andere Methode aufrufen (heat)). Zusätzlich kriegt man ein Objekt, d.h. man hat einen Zustand, den eine Funktion nicht haben kann. Das hat manchmal auch Vorteile.


Ersteres würde auch mit zwei Lambda-Ausdrücken gehen. Zweiteres stimmt, aber ist halt nunmal nicht immer gegeben. Es hat ja niemand hier etwas gegen Objekte, aber sie sind nicht das Allheilmittel, als das sie in Java angepriesen werden.

Quoted


Aber alles in allem ist es eine runde OO-Sprache, mit der man viel machen kann und die sicherlich auch ihre Stärken hat (vom Handy bis zum Server z.B.)


Java ist einfach runtergezähmt auf den kleinsten allgemein verstandenen Nenner, und selbst da steckt noch der Wurm drin (primitive Datentypen, ineffiziente Generics, C-switch), was der Hype aber gut ausgeglichen hat. Nur weil etwas verbreitet ist, ist es noch lange nicht für jeden speziellen Fall die beste Lösung... eigentlich fallen mir viel mehr Beispiele ein, wo das Gegenteil der Fall ist :rolleyes:

dluebke

Trainee

  • "dluebke" is male

Posts: 37

Date of registration: Aug 26th 2004

26

Friday, August 4th 2006, 2:58pm

Quoted

Original von denial
GUI sollte IMHO niemals in Quellcode umgesetzt werden. Der Code ist immer häßlich und sogar kompiliert noch riesengroß. Zu Atari ST Zeiten gab es .rsc Dateien, Apple hat(te?) seine Resource Forks, unter Windows gibt es Resourcen Segmente und mit libglade kann man GLADE XML Dateien durch drei Zeilen Code einbinden. Ein Vorteil ist, daß man die GUI übersetzen, oder sogar komplett umstellen kann, ohne auch nur eine Zeile des Codes anzufassen. Das einzige was ein GUI Builder an Code erzeugen darf, sind leere Stubs für die gewünschten Handler.

Ein Beispiel:
gtk-gnutella 0.96.1 hat in src/ui/gtk/gtk1 eine interface-glade.c Datei deren zweite Zeile "DO NOT EDIT THIS FILE - it is generated by Glade." lautet.
Diese Datei ist 946848 Byte groß und kompiliert auf 428426 Byte (allein das Textsegment).
Die dazugehörige .glade Datei ist gzip komprimiert (damit kann der XML Parser umgehen) 46290 Byte groß.
Libglade 0.17 ist kompiliert 98340 Byte groß.
Ok, libxml und libz kommen noch dazu, aber die könnten vom Programm sowieso gebraucht werden. Außerdem linken wir dynamisch.


Wie der GUI-Code gespeichert wird, ist finde ich relative Geschmackssache. Mir kann keiner erzählen, dass der Anwender die GUI ändern wird, insofern hat das externe Speichern keinen Vorteil. Wird die GUI in den Binärresourcen, die übrigens nicht dafür eigentlich gedacht waren XML aufzunehmen, gespeichert, so ist das eh hinfällig, da man nur mit Entwicklertools rankommt.

XML hat den Nachteil, dass man halt wieder eine Schicht zwischen der eigentlichen Ausführung und der Darstellung hat (nämlich den XML-GUI-Interpreter). Dies kann ein Vorteil sein, wenn das neue Datenformat Vorteile hat, aber man verliert auch Kontrolle. Zumal noch zusätzlich das "drankleben" der Logik dann nicht so leicht ist. Und mir kann keiner sagen, dass 50KByte gepacktes XML gerade performant zu lesen ist :-) Aber Performanz ist in diesen Bereichen heutzutage meistens eh nicht so wichtig. Ich kenne nun Gtk nur sehr flüchtig, aber es ist ein Grauss. Dass man da möglichst viel in XML auslagern möchte, um es nicht selber zu schreiben, kann ich verstehen :-)

Daniel

dluebke

Trainee

  • "dluebke" is male

Posts: 37

Date of registration: Aug 26th 2004

27

Friday, August 4th 2006, 3:18pm

Quoted

Original von julianr
Weiß nicht, ich finde Einrückung reicht, vielleicht bin ich Pascal-vorgeschädigt.
Du gehst aber anscheinend davon aus, dass man das nur verwenden würde, um riesige Algorithmen aufzuteilen. Sehe ich anders, auch in einer Funktion, die keinen Bildschirm füllt, will man vllt einfach drei Schritte, die man an wenigen verschiedenen Stellen auf irgendeine Variable anwendet, kurzerhand auslagern - einfach um Redundanz auf dem Minimum zu halten. Und vielleicht sieht die Ursprungsfunktion von kleinen Wiederholungen befreit auf einmal ja auch sehr kompakt und eindeutig aus, wenn die innere Funktion auch noch gut benannt wurde? ;)


Weiß nicht, wie oft das vorkommt?! Aber in dem Fall sehe ich auch ehrlich gesagt kein Problem, das als private-Methode/Funktion über die entsprechende Methode zu tun.

Quoted


Quoted


Mal abgesehen von J2EE <= 1.4 (was in der 1.5/5.0er schon deutlich besser aussieht) gibt es in Java nicht mehr Fließbandcode als in anderen Sprachen auch.

Bei GUIs sehe ich es so, dass man die einfach nicht als Quelltext speichern sollte. Ich dachte eher an triviale Sachen wie Getter/Setter (pfui von vornherein ;) ).


Was ist daran pfui? Gerade diese sind wichtig für das Data Hiding...

Quoted


Oder eben den Code, den man braucht, um den Mangel an Lambda-Ausdrücken auszugleichen - wobei einem das die IDE ja nicht einmal abnimmt, afaik.

Quoted


Also erstmal gibt es keine Funktionen in objektorientierten Sprachen, sondern halt nur - welch Überraschung - Objekte (und Klassen). Das ist wohl sein Hauptproblem.

Sein (und mein) Hauptproblem ist wohl, dass Java krampfhaft einseitig objektorientiert ist - und der Horizont der Sprache da auch endet.


Wie ich oben schon sagte, jedes Konzept hat seine Vor- und Nachteile. OO ist eine Art von Programmierung, die sicher viele Vorteile hat. Aber es gibt auch noch genug andere Sprachen. Darum ging es mir aber auch nicht. In dem Artikel ging es halt um Schwächen, die in meinen Augen keine sind, weil sie leicht in OO nachzubilden sind.

Quoted


Quoted


  • Funktional macht es keinen Unterschied, ob ich eine Funktion oder ein Objekt mit definierter Methode übergebe.
  • Ich kenne wenige Fälle, in denen ich eine Schleife wegabstrahieren musste.


Es macht auch keinen Unterschied, ob man nun Objekte verwendet, oder structs und viele globale Funktionen mit einem this-Zeiger.


Naja, mit den Interfaces wird es dann schwieriger :-) Aber generell ist das funktional gleich, ja. Und nicht umsonst wird es im Linux-Kernel z.B. so gemacht, weil man nur C nehmen möchte. Aber das Konzept an sich ist halt stark für größere Systeme und die Denkweise (auf die es primär ankommt) halt ebenso.

Quoted


Lambdas in C# sind auch nur platter syntaktischer Zucker, so wie Objekte in vielen Sprachen. Letztendlich kann man alles nachbauen. Aber wenn eine Sprache einen einfach schreiben lässt, was man denkt, dann hat das nunmal nur Vorteile. Hallo Ruby:

Source code

1
2
Person heinz = personen.find { ?|p| p.name == "Heinz" }
personen.sort_by { |p| p.schuhgröße }


Für das erste würde man in vielen Sprachen eine for-Schleife nehmen - wie für fast alles, weswegen man erstmal genau hingucken muss, was eigentlich passiert. Für das zweite eine Funktion, der man irgendeine Art von Functor übergibt.
Niemand zwingt einen dazu, die zu Grunde liegenden Schleifen (oder was auch immer) wegzuabstrahieren, aber an Les- und Wartbarkeit macht man da imho einen ganz schönen Gewinn.


Mit dem Nachteil, dass die Sprache doch recht viele Syntaxkonstrukte braucht (?, ||). Wenn man die Methoden und Klassen richtig genannt ist das aber wohl wahr. Aber das liegt auch zu einem Großteil daran, dass halt die Sprache das mitbringt. Müsste man jetzt sort_by und find selber noch programmieren, wäre es halt mehr Aufwand. Java hat auch Sortiermechanismen etc. die einem das meiste abnehmen (was dazu führt, dass Studenten noch nicht mal mehr ein Array in 60 Minuten sortieren können). Der Vorteil, der hier im Beispiel am meisten zum Tragen kommt, ist halt das sehr späte Binden, d.h. man darf p.name schreiben, ohne halt direkt schon zu wissen, was für ein Objekt da kommen mag. Es wird halt einfach die Eigenschaft ausgelesen. Das ist in Java mit sehr harter Typisierung schwieriger, dafür passieren einem halt auch weniger Typecast u.ä. Fehler. Das ist wiederum sehr Geschmackssache. Ich kenne Leute, die finden das eine besser, die anderen das andere. Ich persönlich habe gerne einen Compilercheck, PHP&Co würde ich nur mit erhöhten Testaufwand machen.

Quoted


Quoted


Eigentlich dürfte sie deshalb auch nicht mehr Cook heißen sondern AlertAndCallAFunction. Und alleine daran sieht man, dass der Gute soweit wegabstrahiert hat, dass es doch sehr generisch und beliebig geworden ist.


Schon, aber andersrum finde ich es oft ziemlich einschränkend, dass man sich als Autor einer Klasse in Java schon im Voraus Gedanken machen muss, was man damit vielleicht mal alles machen will (konkret, welche Interfaces man implementiert). In Fragen der Typsicherheit fehlt imho vielen (allen?) Sprachen der Mittelweg.


Warum muss ich mir immer vorher überlegen, was die Klasse können soll. Ein Interface zuzufügen ist nun das leichteste der Welt...

Quoted



Quoted


...die dann sogar mehr als eine Methode haben dürfen, was dann sogar noch besser ist, z.B. nicht nur mit 2 Parametern arbeiten sondern über eine Liste iterieren, dabei eine Methode aufrufen (putInPot) und zum Schluß eine andere Methode aufrufen (heat)). Zusätzlich kriegt man ein Objekt, d.h. man hat einen Zustand, den eine Funktion nicht haben kann. Das hat manchmal auch Vorteile.


Ersteres würde auch mit zwei Lambda-Ausdrücken gehen. Zweiteres stimmt, aber ist halt nunmal nicht immer gegeben. Es hat ja niemand hier etwas gegen Objekte, aber sie sind nicht das Allheilmittel, als das sie in Java angepriesen werden.


Allheilmittel ist halt gar nichts. Aber man muss sich irgendwann für ein Konzept entscheiden und das durchziehen. Macht man alles, kann man alles und auch gar nichts und was dabei rauskommt, kann sich jeder z.B. bei BPEL ansehen, wo man gleich zwei Arten hat, die gleichen Dinge zu tun. Es geht im Wesentlichen um Konsistenz. Man tut sich leichter, wenn alles ein Objekt ist, als wenn da alles rumfliegt. Genauso tut man sich leichter, wenn man nur Quelltext hat anstatt Quelltext, XML und HTML und SQL und k.A. was in einem Projekt (das gilt übrigens auch für die GUI-Diskussion).

Quoted



Quoted


Aber alles in allem ist es eine runde OO-Sprache, mit der man viel machen kann und die sicherlich auch ihre Stärken hat (vom Handy bis zum Server z.B.)


Java ist einfach runtergezähmt auf den kleinsten allgemein verstandenen Nenner, und selbst da steckt noch der Wurm drin (primitive Datentypen, ineffiziente Generics, C-switch), was der Hype aber gut ausgeglichen hat. Nur weil etwas verbreitet ist, ist es noch lange nicht für jeden speziellen Fall die beste Lösung... eigentlich fallen mir viel mehr Beispiele ein, wo das Gegenteil der Fall ist :rolleyes:


Java war die erste Sprache dieser Art mit diesem Anspruch. Sie ist gewachsen und die primitven Datentypen kommen daher, dass die Rechner und die VM-Technik damals noch zu langsam waren. Die Generics zur Laufzeit sind wirklich komisch, aber genau deswegen möchte ich Compiler-Checks haben :-) Den switch muss man nicht benutzen. Klar hat Java einen Hintergrund und sicherlich ihre Schwächen... Aber wie gesagt, auch seine Stärken. Und ich glaube, es braucht sich keiner Illusionen darüber machen, dass er nach dem Studium mit einer OO-Sprache programmieren wird, wenn er denn programmieren wird. Und die Konzepte lernt man mit Java ganz gut. Und ob es dann Java oder Visual Basic wird - mein Gott. Ich hoffe nur, dass das Design dann gut wird, d.h. ein großes System vernünftig zerlegt wird.

Daniel

denial

Erfahrener Schreiberling

  • "denial" is male

Posts: 394

Date of registration: Feb 18th 2003

Location: Göttingen

Occupation: Linux Coder (ex Mathe SR Inf Student)

28

Friday, August 4th 2006, 4:19pm

Quoted

Original von dluebke

Quoted

Original von julianr
Bei GUIs sehe ich es so, dass man die einfach nicht als Quelltext speichern sollte. Ich dachte eher an triviale Sachen wie Getter/Setter (pfui von vornherein ;) ).


Was ist daran pfui? Gerade diese sind wichtig für das Data Hiding...
Manchmal ist Data Hiding auch absolut überflüssig. Wenn ich eine Variable X habe und ich bin mir absolut sicher, daß sie niemals etwas anderes als ein int sein wird (weil etwas anderes keinen Sinn machen würde) und ich will sie von außen les- und setzbar machen, dann sollte es legitim sein sie als public zu deklarieren, statt Getter und Setter zu schreiben.

In C++ waren Getter und Setter noch zu verkraften. Da konnte der Compiler sie in den meisten Fällen inlinen. Aber in Java, wo es keine Headerdateien gibt, geht das nicht mehr.

julianr

Erfahrener Schreiberling

Posts: 298

Date of registration: Oct 13th 2005

Location: I live in a giant bucket.

29

Friday, August 4th 2006, 5:13pm

Quoted


Was ist daran pfui? Gerade diese sind wichtig für das Data Hiding...


Naja, sie sind etwas besser als public-Variablen.
Sicher gibt es öfter mal Funktionen, die mit get und set anfangen, aber imho sollte man sich immer gut überlegen, ob man die anlegt (und deshalb finde ich automatisch generierte Getter/Setter-Paare eher kontraproduktiv). Wenn man von außen etwas mit einem Objekt tut, was übermäßig viel get/set benötigt, sollte man sich fragen, ob das nicht eher ins Objekt selbst gehört.

Quoted


In dem Artikel ging es halt um Schwächen, die in meinen Augen keine sind, weil sie leicht in OO nachzubilden sind.


Man kann Schrauben auch verhältnismäßig leicht mit einem Hammer in die Wand schlagen. Aber kein normaler Mensch würde sich deshalb auf nur ein Werkzeug festnageln lassen (uh, SCNR). Genau den Weg geht Java damit, sich stur auf OO einzuschießen, und verkauft das auch noch als "Reinheit". Aber dazu unten mehr.

Quoted


Mit dem Nachteil, dass die Sprache doch recht viele Syntaxkonstrukte braucht (?, ||).

Der Vorteil, der hier im Beispiel am meisten zum Tragen kommt, ist halt das sehr späte Binden, d.h. man darf p.name schreiben, ohne halt direkt schon zu wissen, was für ein Objekt da kommen mag.


Das "?" war nur ein Typo, eigentlich braucht man in beiden Fällen die gleiche {|| }-Syntax.

Ich habe auch nichts gegen typisierte Sprachen, kommt immer darauf an, was man machen will. Aber die unterscheiden sich hierbei nicht viel von den untypisierten. Natürlich ist die Syntax in einer einfach gebauten, stark typisierten Sprache (C#2.0) erstmal unhandlicher:

Source code

1
List<Person> erwachsene = personen.FindAll(delegate(Person p) { return p.alter >= 18; });


Selbst das ist ja wohl noch schicker als alles, was Java zu bieten hat. Und außerdem gibt es ja immer noch das schöne Konzept der Typinferenz, mit der das dann auf Folgendes schrumpft (C#3.0):

Source code

1
2
3
4
// Mit Typechecks
List<Person> erwachsene = personen.FindAll((Person p) => p.alter >= 18);
// Mit Typinferenz
var erwachsene = personen.FindAll(p => p.alter >= 18);


Quoted


Warum muss ich mir immer vorher überlegen, was die Klasse können soll. Ein Interface zuzufügen ist nun das leichteste der Welt...


Solange man jeden im Projekt verwendeten Quellcode frei verändern möchte und darf. In C++ wären sicher nicht so viele geniale template-Ideen entstanden, wenn die Entwickler der Standardbibliothek sich vorher alle nur erdenklichen Konzepte hätten ausdenken und als Interfaces formulieren müssen.

Quoted


Allheilmittel ist halt gar nichts. Aber man muss sich irgendwann für ein Konzept entscheiden und das durchziehen. [...] Man tut sich leichter, wenn alles ein Objekt ist, als wenn da alles rumfliegt.


Und um darauf zurückzukommen, ich glaube genau hier werden wir uns nicht mehr einig. Ich finde es nicht nur unnötig, sich auf eine einzige Denkweise zu festzulegen, sondern auch sehr einschränkend. Natürlich kann man sich in zu vielen Ansätzen verrennen, aber in einem einzigen genauso. Und in der Zeit, die man braucht, um jedes Problem in die passende Form zu pressen, hätte man auch zwei Sprachmittel mehr lernen können.

  • "Joachim" is male

Posts: 2,863

Date of registration: Dec 11th 2001

Location: Hämelerwald

Occupation: Wissenschaftlicher Mitarbeiter (Forschungszentrum L3S, TU Braunschweig)

30

Friday, August 4th 2006, 6:15pm

Quoted

Original von denial
Manchmal ist Data Hiding auch absolut überflüssig. Wenn ich eine Variable X habe und ich bin mir absolut sicher, daß sie niemals etwas anderes als ein int sein wird (weil etwas anderes keinen Sinn machen würde) und ich will sie von außen les- und setzbar machen, dann sollte es legitim sein sie als public zu deklarieren, statt Getter und Setter zu schreiben.
Damit nimmt sich jedoch (zumindest in Java) die Möglichkeit, auf Änderungen dieser Variable (oder auf Zugriffe allgemein) zu reagieren. Sollte diese Funktionalität irgendwann einmal benötigt werden, müssen Getter und Setter eingeführt werden, was natürlich auch Änderungen aller zugreifenden Klassen nach sieht zieht.

Zudem finde ich es ganz gut, Zugriffe "aktiv" zu formulieren wie es durch Getter und Setter der Fall ist: "Liebes Objekt x, bitte sage mir den Wert der Variablen y". Dies entspricht finde ich der "natürlichen Sichtweise": man greift nicht einfach auf fremde Daten zu, sondern fordert andere Personen zum handeln auf.
The purpose of computing is insight, not numbers.
Richard Hamming, 1962

dluebke

Trainee

  • "dluebke" is male

Posts: 37

Date of registration: Aug 26th 2004

31

Monday, August 7th 2006, 1:12pm

OMG, ich habe ehrlich gesagt nicht weiter vor, mich hier auf eine Diskussion, wessen Programmiersprache/-stil hat den längsten... einzulassen.

Quoted

Original von julianr

Quoted


Was ist daran pfui? Gerade diese sind wichtig für das Data Hiding...

Naja, sie sind etwas besser als public-Variablen.
Sicher gibt es öfter mal Funktionen, die mit get und set anfangen, aber imho sollte man sich immer gut überlegen, ob man die anlegt (und deshalb finde ich automatisch generierte Getter/Setter-Paare eher kontraproduktiv). Wenn man von außen etwas mit einem Objekt tut, was übermäßig viel get/set benötigt, sollte man sich fragen, ob das nicht eher ins Objekt selbst gehört.


Getter und setter sind viel besser als Variablen. Data Hiding ist ein verdammt wichtiges Konzept - nicht nur für OO. Dass man getter und setter generieren kann, ist eine Komfortfunktion der IDE. Ich habe noch keine IDE gesehen, die automatisch damit meinen Quelltext zumüllt. Und wenn würde ich sie sicher nicht benutzen, weil ich gerne Herr meiner Quelltexte bin.

Quoted


Quoted


In dem Artikel ging es halt um Schwächen, die in meinen Augen keine sind, weil sie leicht in OO nachzubilden sind.


Man kann Schrauben auch verhältnismäßig leicht mit einem Hammer in die Wand schlagen. Aber kein normaler Mensch würde sich deshalb auf nur ein Werkzeug festnageln lassen (uh, SCNR). Genau den Weg geht Java damit, sich stur auf OO einzuschießen, und verkauft das auch noch als "Reinheit". Aber dazu unten mehr.


Nur dass diese Funktoren sicherlich keine Schraube für einen Hammer sind, sondern sich OO-mäßig elegant lösen lassen...
"Reinheit" ist aber ein wichtiges Kriterium. Denn Code ist nur dann vernünftig lesbar und vor allem später wartbar, wenn man möglichst wenig Denkweisen und Konzepte miteinander vermischt. SQL im Quelltext ist ein Graus und je mehr man zusammenmanscht, desto schlimmer wird's. Klar gibt es schöne Varianten Dinge zu tun und das eine Beispiel sah ja auch elegant (von der Zeilenanzahl) aus. Aber es kommt halt nochmal was dazu und für viele Arten von Anwendungen (s. wieder richtige Sprache für das richtige Problem) ist es sicherlich nicht von Vorteil.

Quoted


Quoted


Mit dem Nachteil, dass die Sprache doch recht viele Syntaxkonstrukte braucht (?, ||).

Der Vorteil, der hier im Beispiel am meisten zum Tragen kommt, ist halt das sehr späte Binden, d.h. man darf p.name schreiben, ohne halt direkt schon zu wissen, was für ein Objekt da kommen mag.


Das "?" war nur ein Typo, eigentlich braucht man in beiden Fällen die gleiche {|| }-Syntax.

Ich habe auch nichts gegen typisierte Sprachen, kommt immer darauf an, was man machen will. Aber die unterscheiden sich hierbei nicht viel von den untypisierten. Natürlich ist die Syntax in einer einfach gebauten, stark typisierten Sprache (C#2.0) erstmal unhandlicher:

Source code

1
List<Person> erwachsene = personen.FindAll(delegate(Person p) { return p.alter >= 18; });


Selbst das ist ja wohl noch schicker als alles, was Java zu bieten hat.


Java bietet kein Suchen auf den Listen selbst aus der Klassenbibliothek an, das stimmt wohl. Aber von der Syntax her finde ich es nicht "schöner" als die Java-Variante

Source code

1
2
3
4
5
6
List<Person> erwachsener = personen.find(new Matcher() {
  public void match(Person p)
  {
    return p.getAlter() >= 18;
  }
});


Der Code hier ist ein wenig länger, aber es ist alles nur Deklarationscode. Man sieht dafür deutlicher was passiert und man kann die Dinger halt wiederverwenden, auslagern etc und dann ist es viel besser lesbar (und wartbar) als alle Beispiele darüber:


Source code

1
List<Person> erwachsener = personen.find(PersonenList.ADULT_MATCHER);


(<spinn>es gibt auch Länder, da ist man nicht mit 18 volljährig und dann wird das in den anderen Lösungen ein endloses gebastel von > = && und k.A. was....</spinn>)

Quoted


Und außerdem gibt es ja immer noch das schöne Konzept der Typinferenz, mit der das dann auf Folgendes schrumpft (C#3.0):

Source code

1
2
3
4
// Mit Typechecks
List<Person> erwachsene = personen.FindAll((Person p) => p.alter >= 18);
// Mit Typinferenz
var erwachsene = personen.FindAll(p => p.alter >= 18);



Es ist jetzt alles subjektiv, aber ich finde nicht, dass das super-lesbar ist (ein Grund mehr, diese Diskussion dann so stehen zu lassen)... Der Unterschied zwischen => und >= ist mir nicht groß genug...

Quoted


Quoted


Warum muss ich mir immer vorher überlegen, was die Klasse können soll. Ein Interface zuzufügen ist nun das leichteste der Welt...

Solange man jeden im Projekt verwendeten Quellcode frei verändern möchte und darf. In C++ wären sicher nicht so viele geniale template-Ideen entstanden, wenn die Entwickler der Standardbibliothek sich vorher alle nur erdenklichen Konzepte hätten ausdenken und als Interfaces formulieren müssen.


Hmm, also das habe ich überhaupt nicht verstanden... Die C++-Leute haben sich die ganzen Dinger überlegt oder übernommen.
Klar kann ich meinen Code ändern. Code, den ich nicht ändern kann, kann ich nur verwenden - egal in welcher Sprache. Und Änderungen daran muss man halt dann immer weitergeben in irgendwelche Gremien etc. Es geht um mein Design, was ich als Designer mache.

Quoted


Quoted


Allheilmittel ist halt gar nichts. Aber man muss sich irgendwann für ein Konzept entscheiden und das durchziehen. [...] Man tut sich leichter, wenn alles ein Objekt ist, als wenn da alles rumfliegt.


Und um darauf zurückzukommen, ich glaube genau hier werden wir uns nicht mehr einig. Ich finde es nicht nur unnötig, sich auf eine einzige Denkweise zu festzulegen, sondern auch sehr einschränkend. Natürlich kann man sich in zu vielen Ansätzen verrennen, aber in einem einzigen genauso. Und in der Zeit, die man braucht, um jedes Problem in die passende Form zu pressen, hätte man auch zwei Sprachmittel mehr lernen können.


Es geht ja nicht darum, dass einer das kann, sondern das ein ganzes Team und noch drei Teams mehr später in der Wartung das können. Ich habe nichts dagegen einen passenden Ansatz für ein Gesamtproblem zu nehmen und dann evtl. entsprechend so zu unterteilen, dass man Untersysteme anders löst. Aber schon das ist dann grenzwertig. Es gibt nicht nur Programmierer, die Überflieger sind (der Java-Prüfungsthread hat das ja auf eindrucksvolle Weise bewiesen...). Und wie gesagt, wenn ich alles zusammenmische, gibt es nur Chaos...

So, aber wie schon mehrfach angedeutet, mag ich keine Diskussionen über Programmiersprache XYZ ist besser etc. Es gibt halt keine Dominanzbeziehung bei Programmiersprachen...

Daniel

julianr

Erfahrener Schreiberling

Posts: 298

Date of registration: Oct 13th 2005

Location: I live in a giant bucket.

32

Friday, August 25th 2006, 8:07pm

Quoted


Hmm, also das habe ich überhaupt nicht verstanden... Die C++-Leute haben sich die ganzen Dinger überlegt oder übernommen.


Was ich meinte ist, dass eine Klasse in C++ keine Interfaces erfüllen muss, um in einem template verwendet werden zu können - man hat also völlige Handlungsfreiheit, und viele geniale Libraries tun Dinge mit Objekten der Standardbibliothek, die sicher nie vorhergesehen wurden. Sollte nur ein Beispiel für einen Fall sein, in dem die Kopplung Interfaces<>Generics hinderlich ist/gewesen wäre (weil man der Standardbibliothek nicht kurzerhand neue Interfaces hinzufügen kann).

Ich habe den Thread jetzt aber nicht aufgewärmt, um darüber zu diskutieren, was möglich sein sollte oder nicht darf - sondern weil ich gerade in einem anderen Gespräch darauf hingewiesen wurde, dass die Java-Gemeinde auch gerade an diesem Problem arbeitet (Respekt, hätte ich nicht erwartet). Ich fands zumindest interessant: http://gafter.blogspot.com/2006/08/closures-for-java.html

This post has been edited 1 times, last edit by "julianr" (Aug 25th 2006, 8:08pm)


AnyKey

Erfahrener Schreiberling

Posts: 451

Date of registration: Dec 11th 2001

Location: H-Town

Occupation: Student

33

Tuesday, September 12th 2006, 4:09pm

BTT:

http://forum.java.sun.com/thread.jspa?th…ssageID=2292039



oder wart ihr noch nicht fertig?

"Der Mensch braucht Schubladen." -- Any Key