Discussion:
Design-Frage
(zu alt für eine Antwort)
Mike Wesling
2008-10-12 09:12:39 UTC
Permalink
Hallo,

Design im Betreff klingt vielleicht etwas übertrieben, aber ich will
einfach wissen, wie man gewisse Dinge Design-Technisch schön
implementiert. Vor allem, ob ihr einen Haufen (private) Methoden in
einer Klasse macht, obwohl diese nur 3-4 Zeilen haben, oder doch eher
versucht, mehr an einem Ort zu kapseln.

Ich habe festgestellt, dass es im Grunde die Möglichkeit gibt, den
ganzen Code auch sehr übersichtlich innerhalb eines Methodenrumpfes
abzuarbeiten. Die andere Variante wäre, verschiedene Bereiche daraus zu
machen und diese dann fast so "Workflow"-mässig in der vom User
bestimmten Methode aufzurufen. Also:

public MyClass()
{
Do_Part_1();
...
Do_Part_10();
}

private void Do_Part_1()
{
// do something here
}


Wenn man das schön in Methoden aufteilt, dann kann es auch einige
Methoden geben, die z.B. Attribute für die weitere Verarbeitung
ermitteln. Andere Methoden brauchen diese dann, um ihre Arbeit
verrichten zu können.

Macht Ihr das so, dass es einen Klassenmember gibt (z.B. eine
Collection), der dann aber nicht wie bei public-Methoden als Parameter
übergeben wird? Also sprich, jede private Methode schreibt/liest ihre
Informationen aus dieser Klassen-"Globalen". Also:

private List MyList;
public MyClass()
{
Do_Part_1();
...
Do_Part_10();
}
private void Do_Part_1()
{
... // Do something
MyList.Add(my_information);
}
private void Do_Part_1()
{
... // Read something from MyList
}


Oder ist es besser, dass man jede private Methode eher gestaltet wie
eine public-Methode und gute Signaturen baut? Das würde dann aber auch
bedeuten, dass die private Methode "Do_Part_1()" einen Rückgabewert hat
und diese Information dann an den Klassen-Member übergibt. Also z.B.:

private List MyList;
public MyClass()
{
MyList = Do_Part_1();
...
}
private List Do_Part_1()
{
List InternalList;

... // Do something

InternalList.Add(my_information);

return InternalList;
}



Das nächste betrifft Informationen, die immer wieder zwischen
verschiedenen Klassen geteilt werden müssen. Zum Beispiel kann es sein,
dass man sich einmal einen bestimmten Pfad zu einer Datei zusammenbauen
will und dann von mehreren Klassen aus auf diesen zugreift. Oder man
möchte Konstanten in mehreren Klassen verwenden. Baut Ihr Euch dazu dann
immer eine "Datenhaltungs-Klasse" über einen Singleton oder wie macht
Ihr das?


Ich weiss nicht, aber bei guter Klassenaufteilung scheinen immer alle
Zugriffe gut aufzugehen, wie bei einem guten Schachspiel, aber wenn das
nicht der Fall ist, dann fragt man sich immer, wie man jetzt die
Informationenen, die man in einer anderen Klasse schon einmal ermittelt
hat, nun in die jetzige Klasse rüber bekommt. Vielleicht könnt Ihr mir
da mal wieder ein bisschen helfen!?!?
Michael Paap
2008-10-12 09:44:09 UTC
Permalink
Post by Mike Wesling
Macht Ihr das so, dass es einen Klassenmember gibt (z.B. eine
Collection), der dann aber nicht wie bei public-Methoden als Parameter
übergeben wird? Also sprich, jede private Methode schreibt/liest ihre
Informationen aus dieser Klassen-"Globalen".
Informationen, die den Zustand eines Objekts abbilden, stehen in
Attributen. Und private Methoden dürfen *selbstverständlich* den Zustand
"ihres" Objekts ändern.

Etwas anderes sind "Zwischeninformationen", die *nicht* zum Zustand des
Objekts gehören, sondern die lediglich eine Methode quasi dienstleistend
für eine andere berechnet, dann werden diese als Parameter übergeben
bzw. als Rückgabewert zurückgegeben.

Gruß,
Michael
Mike Wesling
2008-10-12 12:03:18 UTC
Permalink
Post by Michael Paap
Post by Mike Wesling
Macht Ihr das so, dass es einen Klassenmember gibt (z.B. eine
Collection), der dann aber nicht wie bei public-Methoden als Parameter
übergeben wird? Also sprich, jede private Methode schreibt/liest ihre
Informationen aus dieser Klassen-"Globalen".
Informationen, die den Zustand eines Objekts abbilden, stehen in
Attributen. Und private Methoden dürfen *selbstverständlich* den Zustand
"ihres" Objekts ändern.
Schon, aber macht man das in der Praxis nach "gutem Stil" auch so,
darauf zielte meine Frage etwas ab.

Ich kann, wie in meinem OP beschrieben, z.B. alles in der Main-Methode
abhandeln oder das ganze natürlich etwas aufteilen in kleinere Einheiten
und dann nur noch in der main den "Workflow" für die Abarbeitung angeben.

Entsprechend kann es dann passieren, dass die zweite Methode in der
Aufrufreihenfolge mit Daten arbeiten soll, die die erste ermittelt hat.
Ich kann die Daten der ersten Methode (z.B. ein Collection-Typ) als
Rückgabewert zunächst wieder an die Main zurückgeben und diese teilt
dann die Daten als Übergabeparameter der zweiten Methode zu.

Oder ich kann die erste Methode alles in die Klassenvariable schreiben
lassen und aus der liest dann die zweite Methode wieder.

Bei der ersten Variante kann man die Methoden für den späteren Fall sehr
leicht einmal public machen.

Generell steckten in meinem OP zwei Fragen drin:

1) Wie gut ist der Stil, wenn ich Methoden habe, die ohne
Übergabe-/Rückgabeparameter sind und ihre Ergebnisse in eine
Klassenvariable schreiben?

2) Ist es überhaupt guter Stil, dass man alles, was man theoretisch an
Ort und Stelle in der Main ermitteln könnte, auf mehrere sehr kleine
Methoden aufteilt?
Post by Michael Paap
Etwas anderes sind "Zwischeninformationen", die *nicht* zum Zustand des
Objekts gehören, sondern die lediglich eine Methode quasi dienstleistend
für eine andere berechnet, dann werden diese als Parameter übergeben
bzw. als Rückgabewert zurückgegeben.
Zustand des Objektes ist gut gesagt. Wenn ich Klassen nur brauche, um
etwas zu erledigen, dann ist der konkrete Zustand eigentlich gar nicht
so von Bedeutung. Wenn ich aber als Aufrufer weiter mit dem
Klassen-Objekt arbeiten muss, dann sind die Daten bzw. der konkrete
Zustand schon wichtiger.
Michael Paap
2008-10-12 12:22:10 UTC
Permalink
Post by Mike Wesling
Post by Michael Paap
Informationen, die den Zustand eines Objekts abbilden, stehen in
Attributen. Und private Methoden dürfen *selbstverständlich* den Zustand
"ihres" Objekts ändern.
Schon, aber macht man das in der Praxis nach "gutem Stil" auch so,
darauf zielte meine Frage etwas ab.
Ja, so macht man das.
Post by Mike Wesling
Ich kann, wie in meinem OP beschrieben, z.B. alles in der Main-Methode
abhandeln oder das ganze natürlich etwas aufteilen in kleinere Einheiten
und dann nur noch in der main den "Workflow" für die Abarbeitung angeben.
Entsprechend kann es dann passieren, dass die zweite Methode in der
Aufrufreihenfolge mit Daten arbeiten soll, die die erste ermittelt hat.
Du denkst prozedural. Das ist dann ok, wenn es sich um die innersten
Details handelt, irgendwelche Berechnungen zum Beispiel. Aber eine Ebene
drüber hast du keine Daten *mit* denen eine Methode etwas macht, sondern
du hast Objekte, die Methoden haben, mit denen sie ihren Zustand ändern.
Post by Mike Wesling
Ich kann die Daten der ersten Methode (z.B. ein Collection-Typ) als
Rückgabewert zunächst wieder an die Main zurückgeben und diese teilt
dann die Daten als Übergabeparameter der zweiten Methode zu.
Siehe das, was ich weiter unten geschrieben habe.
Post by Mike Wesling
1) Wie gut ist der Stil, wenn ich Methoden habe, die ohne
Übergabe-/Rückgabeparameter sind und ihre Ergebnisse in eine
Klassenvariable schreiben?
Das kommt darauf an. Du denkst prozedural. Und meinst du wirklich eine
Klassenvariable? Oder redest du von Attributen von Objekten? Nehmen wir
an letzteres ist der Fall... ich halte nichts davon, wenn Dinge in
Attribute geschrieben werden, die nicht zum Zustand des Objekts gehören.
Post by Mike Wesling
2) Ist es überhaupt guter Stil, dass man alles, was man theoretisch an
Ort und Stelle in der Main ermitteln könnte, auf mehrere sehr kleine
Methoden aufteilt?
Das kommt darauf an.
Post by Mike Wesling
Zustand des Objektes ist gut gesagt. Wenn ich Klassen nur brauche, um
etwas zu erledigen, dann ist der konkrete Zustand eigentlich gar nicht
so von Bedeutung.
Du denkst prozedural. ;-)
Für bestimmte Anwendungsfälle mag das auch "im Großen" berechtigt sein.
Du siehst ein Programm vor dir, welches ziemlich linear irgendeinen Job
erledigt. Es gibt Daten und es gibt Prozeduren, welche diese Daten
benutzen. Es gibt irgendein "Main". Mit OOP hat das nicht viel zu tun.
Das ist nicht schlimmt, aber nach "gutem Stil" im Sinne von OOP braucht
du dann halt gar nicht erst zu fragen. *g*
Post by Mike Wesling
Wenn ich aber als Aufrufer weiter mit dem
Klassen-Objekt arbeiten muss, dann sind die Daten bzw. der konkrete
Zustand schon wichtiger.
Was ist denn ein "Klassen-Objekt"? Ich glaube, wir sollten erst mal ein
paar Begriffe klären. Schau dir bitte mal aus
http://feu.mpaap.de/1618/faq.pdf den Abschnitt "Variable / Attribut /
Klassenattribut / lokale Variable" an, das könnte die Diskussion
einfacher machen.

Gruß,
Michael
J. Stoever
2008-10-12 13:27:18 UTC
Permalink
Post by Michael Paap
http://feu.mpaap.de/1618/faq.pdf den Abschnitt "Variable / Attribut /
Klassenattribut / lokale Variable" an, das könnte die Diskussion
einfacher machen.
Hast Du was mit dem Urheber dieser FAQ zu tun, oder linkst Du sie nur ?
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt), "aktuell" wird mit "actual" uebersetzt,
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.

Sollte evtl. mal jemand druebergehen und berichtigen, aber ich hatte
jetzt nicht die Energie, die Email-Adresse des Autors zu ersherlockholmesen.
Michael Paap
2008-10-12 14:04:02 UTC
Permalink
Post by J. Stoever
Hast Du was mit dem Urheber dieser FAQ zu tun, oder linkst Du sie nur ?
Ersteres.
Post by J. Stoever
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt),
Was bitte soll denn ein Pointer in diesem Zusammenhang sein? Wie sieht
in Java z.B. ein Pointer auf einen int-Wert aus? Es wird meines Wissens
das gemacht, was bei einer Parameterübergabe passiert. Eben deswegen
bleibt eine Zuweisung an die temporäre Variable ja wirkungslos. Du
solltest mit "Quatsch" evtl. ein bisschen zurückhaltender sein.
Post by J. Stoever
"aktuell" wird mit "actual" uebersetzt,
Hm? Ach so. Ist allerdings hier völlig irrelevant, die Methode könnte
auch blafasel() heißen. Ändere ich aber dennoch mal in current, wobei
"actual" duchaus auch "gegenwärtig" bedeutet.
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
Oh ja. Da wäre Ausdruck wirklich besser. Geändert.
Post by J. Stoever
Sollte evtl. mal jemand druebergehen und berichtigen,
Immer gerne.
Post by J. Stoever
aber ich hatte
jetzt nicht die Energie, die Email-Adresse des Autors zu ersherlockholmesen.
Ja, das Ding steht da ist eigentlich nicht für die Öffentlichkeit,
jedenfalls ist das nicht der Zweck. Die, die es bisher benutzten,
wissen, wo sie nachfragen können.

Aber per Mail muss eh nicht. Mach ruhig hier in der Newsgroup. *g*

Gruß,
Michael
J. Stoever
2008-10-12 14:26:11 UTC
Permalink
Post by Michael Paap
Post by J. Stoever
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt),
Was bitte soll denn ein Pointer in diesem Zusammenhang sein? Wie sieht
in Java z.B. ein Pointer auf einen int-Wert aus? Es wird meines Wissens
das gemacht, was bei einer Parameterübergabe passiert. Eben deswegen
bleibt eine Zuweisung an die temporäre Variable ja wirkungslos. Du
solltest mit "Quatsch" evtl. ein bisschen zurückhaltender sein.
Da liegt wohl eher ein Unterschied in der Sichtweise vor. Ich habe nur
an Objekte gedacht, da Primitives ja nun doch eher die Ausnahme sind,
nicht nur hier. Und Objekte werden selbstverfreilich nicht kopiert.

Ob jetzt "kopiert" das richtige Wort fuer Primitives ist, waere ich mir
auch nicht ganz sicher - int i = 1; int j = i;, wird dabei i "kopiert" ?

Ich persoenlich wuerde es nicht so ausdruecken, was aber fuer die FAQ
egal ist, denn in dem Zusammenhang ist "kopiert" schlicht das falsche
Wort, was auch offensichtlich wird, wenn man sich einen for-each-loop
mit Objekten vorstellt.

Sorry dass ich Dir mit meiner Ausdrucksweise auf die Zehen getreten bin,
ich dachte das waere maximal von Deinem Professor oder aehnlichem.
Haette ich mal auf die URL und den Absender gucken sollen ;)
Michael Paap
2008-10-12 16:32:02 UTC
Permalink
Post by J. Stoever
Da liegt wohl eher ein Unterschied in der Sichtweise vor. Ich habe nur
an Objekte gedacht, da Primitives ja nun doch eher die Ausnahme sind,
nicht nur hier. Und Objekte werden selbstverfreilich nicht kopiert.
Nein, natürlich nicht. Aber Objekte sind auch nicht Werte von Variablen.
Variablen enthalten Referenzen und genau die werden kopiert. Und lass
uns jetzt bloß keine Call by Value / Call by Reference-Debate anfangen,
ich bin diesbezüglich ein wneig ermüdet nach einigen Jahren dclj, in
denen es regelmäßig jemand probiert. Kannst du bei Google-Groups nachlesen.
Post by J. Stoever
Ob jetzt "kopiert" das richtige Wort fuer Primitives ist, waere ich mir
auch nicht ganz sicher - int i = 1; int j = i;, wird dabei i "kopiert" ?
Der Wert wird kopiert.
Post by J. Stoever
Ich persoenlich wuerde es nicht so ausdruecken, was aber fuer die FAQ
egal ist, denn in dem Zusammenhang ist "kopiert" schlicht das falsche
Wort, was auch offensichtlich wird, wenn man sich einen for-each-loop
mit Objekten vorstellt.
Nein, es ist hundertprozentig korrekt. Du musst dir nur klarmachen, dass
Variablen keine Objekte enthalten, sondern Referenzen, siehe oben.
Post by J. Stoever
Sorry dass ich Dir mit meiner Ausdrucksweise auf die Zehen getreten bin,
ich dachte das waere maximal von Deinem Professor oder aehnlichem.
Haette ich mal auf die URL und den Absender gucken sollen ;)
Kein Problem, ich verkrafte einiges. Aber so lange du sowas schreibst,
wie da oben, solltest du es sachte angehen lassen. *g*

Gruß,
Michael
J. Stoever
2008-10-12 17:27:12 UTC
Permalink
Post by Michael Paap
Post by J. Stoever
Ich persoenlich wuerde es nicht so ausdruecken, was aber fuer die FAQ
egal ist, denn in dem Zusammenhang ist "kopiert" schlicht das falsche
Wort, was auch offensichtlich wird, wenn man sich einen for-each-loop
mit Objekten vorstellt.
Nein, es ist hundertprozentig korrekt. Du musst dir nur klarmachen, dass
Variablen keine Objekte enthalten, sondern Referenzen, siehe oben.
Nur, wenn man Pointer und Referenzen im Kopf hat und versteht. Dass
sollte aber bei einem Java-Anfaenger auf gar keinen Fall der Fall sein,
und auch Fortgeschrittene sollten eigentlich nicht so denken.

Ich finde jetzt auch ganz ehrlich nicht, dass wenn jemand davon spricht,
dass Elemente kopiert werden, dass im normalen Sprachgebrauch bedeutet,
dass die Pointer kopiert werden. Habe ich auch noch nie so benutzt gesehen.
Wolfgang Rostek
2008-10-12 18:00:07 UTC
Permalink
...
Post by J. Stoever
Nur, wenn man Pointer und Referenzen im Kopf hat und versteht. Dass
sollte aber bei einem Java-Anfaenger auf gar keinen Fall der Fall sein,
und auch Fortgeschrittene sollten eigentlich nicht so denken.
Nö, nachdem ich das mal zu Anfang verstanden habe,
denke ich nur noch an Pointer und bin damit gut gefahren.
Es ist doch auch so, oder? Die Objekte gehören nicht der
Variablen, sondern sind 'relativ zufällig' an die Variable
gebunden.

Gruß
Wolfgang R.
Michael Paap
2008-10-12 18:23:23 UTC
Permalink
Post by J. Stoever
Nur, wenn man Pointer und Referenzen im Kopf hat und versteht. Dass
sollte aber bei einem Java-Anfaenger auf gar keinen Fall der Fall sein,
Den Anfängern, für die die FAQ geschreiben ist, von der wir reden,
erkläre *ich* Java und OOP. Die wissen, was eine Referenz ist
Post by J. Stoever
und auch Fortgeschrittene sollten eigentlich nicht so denken.
Doch, nur so. Alles andere führt zur Verwirrung.
Post by J. Stoever
Ich finde jetzt auch ganz ehrlich nicht, dass wenn jemand davon spricht,
dass Elemente kopiert werden, dass im normalen Sprachgebrauch bedeutet,
dass die Pointer kopiert werden. Habe ich auch noch nie so benutzt gesehen.
Du bist neu hier, gell? *g*

Ganz im Ernst: Jede andere Sichtweise macht es schwer bis unmöglich, zu
verstehen, was in Java bei einer Parameterübergabe passiert.

Wenn du sagst, es werden Pointer übergeben, dann erwartet man ein
Call-by-Reference-Verhalten, also eben, dass eine Zuweisung sich "nach
außen" auswirkt.

Dem ist aber so nicht.

Gruß,
MIchael
J. Stoever
2008-10-12 19:36:16 UTC
Permalink
Post by Michael Paap
Post by J. Stoever
Nur, wenn man Pointer und Referenzen im Kopf hat und versteht. Dass
sollte aber bei einem Java-Anfaenger auf gar keinen Fall der Fall sein,
Den Anfängern, für die die FAQ geschreiben ist, von der wir reden,
erkläre *ich* Java und OOP. Die wissen, was eine Referenz ist
Tuechtig. Finde ich trotzdem sinnlos fuer Anfaenger.
Post by Michael Paap
Post by J. Stoever
Ich finde jetzt auch ganz ehrlich nicht, dass wenn jemand davon spricht,
dass Elemente kopiert werden, dass im normalen Sprachgebrauch bedeutet,
dass die Pointer kopiert werden. Habe ich auch noch nie so benutzt gesehen.
Du bist neu hier, gell? *g*
Hier ja, in Java nicht.
Post by Michael Paap
Ganz im Ernst: Jede andere Sichtweise macht es schwer bis unmöglich, zu
verstehen, was in Java bei einer Parameterübergabe passiert.
Wir reden aber nicht ueber Parameteruebergaben.
Post by Michael Paap
Wenn du sagst, es werden Pointer übergeben, dann erwartet man ein
Call-by-Reference-Verhalten, also eben, dass eine Zuweisung sich "nach
außen" auswirkt.
Dem ist aber so nicht.
Das trifft zwar auf Zuweisungen zu, aber nicht auf mutability - eine
Aenderung an einem solchen Objekt wirkt sich dann eben doch nach aussen aus.
Michael Paap
2008-10-12 19:46:09 UTC
Permalink
Post by J. Stoever
Wir reden aber nicht ueber Parameteruebergaben.
Sondern über etwas, was ganz genauso funktioniert und sich ganz genauso
verhält.
Post by J. Stoever
Post by Michael Paap
Wenn du sagst, es werden Pointer übergeben, dann erwartet man ein
Call-by-Reference-Verhalten, also eben, dass eine Zuweisung sich "nach
außen" auswirkt.
Dem ist aber so nicht.
Das trifft zwar auf Zuweisungen zu, aber nicht auf mutability - eine
Aenderung an einem solchen Objekt wirkt sich dann eben doch nach aussen aus.
Ja. Beides erklärt mein "Modell" bestens, während deines die
Unwirksamkeit der Zuweisung nicht erklärt.

Abgesehen davon entspricht meines auch noch der Realität.

Aber wie gesagt... ich bin da genauso wenig diskussionswillig, wie bzgl.
der Frage, ob der Mond aus Käse. Du kannst dich ja mal bei den Anderen
hier umhören, wie die das so sehen.

Für mich EOD bzgl. dieses Themas.

Gruß,
Michael
Bernd Hohmann
2008-10-12 20:22:44 UTC
Permalink
Post by Michael Paap
Aber wie gesagt... ich bin da genauso wenig diskussionswillig, wie bzgl.
der Frage, ob der Mond aus Käse. Du kannst dich ja mal bei den Anderen
hier umhören, wie die das so sehen.
Andere? Ich sehe keinen Grund, warum ich ausgerechnet Dir dazu ein
Statement abgeben sollte. Du warst schon immer so und wirst es immer
bleiben - auch in Deiner FAQ

-h
Michael Paap
2008-10-13 05:08:53 UTC
Permalink
Post by Bernd Hohmann
Post by Michael Paap
Aber wie gesagt... ich bin da genauso wenig diskussionswillig, wie bzgl.
der Frage, ob der Mond aus Käse. Du kannst dich ja mal bei den Anderen
hier umhören, wie die das so sehen.
Andere? Ich sehe keinen Grund, warum ich ausgerechnet Dir dazu ein
Statement abgeben sollte.
Hab ich dich gerufen? *g*

Hier soll überhaupt niemand "mir ein Statement abgeben". Um Gottes
Willen... ich will hier doch nichts gewinnen und hab hier nichts zu
verlieren. Hier wird über einen Text diskutiert, den ich geschrieben
habe, in dem es um einen *Sachverhalt* geht. Mein Verhältnis dazu ist
durchaus entspannt und ich sehe den Text nicht wie eine Mutter ihr
geliebtes Kindlein, das sie in Schutz nehmen muss.

Wenn du dich dazu berufen fühlst, kannst du dem J. erklären, was in Java
bzgl. Referenzen und Variablen Sache ist. Dass du das weißt, ist mir
bekannt, und vielleicht versteht J. es auf deine Art besser als auf
meine. Und wenn du dazu keine Lust hast, lässt du es eben.

Was man vielleicht mal klar sagen sollte: Diese "FAQ" war und ist nicht
für die Welt bestimmt. Es handelt sich um eine in Arbeit befindliche
Zusammenstellung von Auszügen aus Beiträgen einer Newsgroup an der
Fernuni Hagen. Und es war auch gar nicht die Absicht, sie hier zu
diskutieren, wobei das ganz gut war, weil sich immerhin ein paar Fehler
gefunden haben.

Die FAQ gehört aber zu einem ganz bestimmten Kurs dort, in dem OOP- und
Java-Kenntnisse vermittelt werden. Das passiert auf eine ganz bestimmte
Weise, insbesondere werden Begriffe halt explizit eingeführt. Dass
WIssen, dass Variablen Referenzen enthalten und nicht die Objekte
selbst, kann ich da getrost voraussetzen.
Post by Bernd Hohmann
Du warst schon immer so und wirst es immer bleiben - auch in Deiner FAQ
Wir beiden kommen nun mal aus völlig unterschiedlichen Ecken und sind
auch in völlig unterschiedlichen Ecken zugange. Ich kann eigentlich ganz
prima damit leben, dass ich in vielen Dingen einem Praktiker wie dir
unterlegen bin, wobei ich manchmal das Gefühl habe, dass du - typisch
für eine bestimmte Art von Praktikern - die Theorie doch etwas arg
gering schätzt. Womit ich aber auch ganz gut leben kann. ;-)

Gruß,
Michael
Bernd Hohmann
2008-10-12 19:51:26 UTC
Permalink
Post by J. Stoever
Post by Michael Paap
Post by J. Stoever
Ich finde jetzt auch ganz ehrlich nicht, dass wenn jemand davon spricht,
dass Elemente kopiert werden, dass im normalen Sprachgebrauch bedeutet,
dass die Pointer kopiert werden. Habe ich auch noch nie so benutzt gesehen.
Du bist neu hier, gell? *g*
Hier ja, in Java nicht.
Popcorn auspack (*)

Bernd

* Java seit 1.0.3 - und da dürfte ich der Senior hier sein.
Frank Buss
2008-10-12 20:05:01 UTC
Permalink
Post by Bernd Hohmann
* Java seit 1.0.3 - und da dürfte ich der Senior hier sein.
Ich verwende es schon seit 1.0.2 (da sieht man mal wieder, daß man langsam
alt wird :-) siehe z.B. das Java Buch, bei dem ich Hauptautor war:

http://www.amazon.de/Programmier-Training-Java-Frank-Buß/dp/3815813034
--
Frank Buss, ***@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Bernd Hohmann
2008-10-12 20:40:34 UTC
Permalink
Post by Frank Buss
Post by Bernd Hohmann
* Java seit 1.0.3 - und da dürfte ich der Senior hier sein.
Ich verwende es schon seit 1.0.2 (da sieht man mal wieder, daß man langsam
1.0.2... da bimmelt es irgendwo bei mir. Die IBM-Portierung nach OS/2
war da so muckig.

Aber mit dem Buch trete ich Dir den Titel "java-senior" freiwillig ab -
Java war da für mich nur ein Experiment um mal reinzufühlen, wie man
unseren Klotz an Applikationen mal auf was portables schieben kann.

Liebes,
Bernd
Paul Ebermann
2008-10-12 14:49:10 UTC
Permalink
Post by J. Stoever
Post by Michael Paap
http://feu.mpaap.de/1618/faq.pdf den Abschnitt "Variable / Attribut /
Klassenattribut / lokale Variable" an, das könnte die Diskussion
einfacher machen.
Hast Du was mit dem Urheber dieser FAQ zu tun, oder linkst Du sie nur ?
Nun, sie steht auf einer Seite seiner Domain, und als Verfasser
im PDF ist "Michael Paap" angegeben.
Post by J. Stoever
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt)
Das ist das gleiche - der "jeweils naechste Wert" des Arrays
ist ja gerade ein Pointer (ausser bei Arrays von primitiven
Typen).
Post by J. Stoever
, "aktuell" wird mit "actual" uebersetzt,
Du meinst "'actual' wird mit 'aktuell' uebersetzt'?

Da sollte wirklich "konkret" stehen ... (Seite 8, wo es
um Parameter geht.)
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
Hmm, finde ich gerade nicht.

(Allerdings habe ich gerade auf Seite 9 bei der Verwendung
von new zwei Fehler gefunden - Person ist doch kein Subtyp von
String (es sei denn, du hast String gehackt, oder verwendest
eine eigene Klasse dieses Namens, was ich fuer eine FAQ, in
der es nicht um dieses Thema geht, sehr verwirrend faende).


Paul
PS: Gerade bemerkt, dass ich etwas speat dran bin mit meiner
Antwort, und einige der Fehler schon korrigiert sind - aber
vielleicht hilft es ja trotzdem ...
--
Nun ludigxas: : ()
J. Stoever
2008-10-12 16:10:04 UTC
Permalink
Post by Paul Ebermann
Post by J. Stoever
Hast Du was mit dem Urheber dieser FAQ zu tun, oder linkst Du sie nur ?
Nun, sie steht auf einer Seite seiner Domain, und als Verfasser
im PDF ist "Michael Paap" angegeben.
Mea culpa.
Post by Paul Ebermann
Post by J. Stoever
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt)
Das ist das gleiche - der "jeweils naechste Wert" des Arrays
ist ja gerade ein Pointer (ausser bei Arrays von primitiven
Typen).
Nein, das ist ein sehr konkreter Unterschied:

for (Point p : points) { p.x = 10; }

hat eine direkte Wirkung auf die tatsaechlichen Elemente in points.
Wuerden die da kopiert werden, waere dem nicht so.
Post by Paul Ebermann
Post by J. Stoever
, "aktuell" wird mit "actual" uebersetzt,
Du meinst "'actual' wird mit 'aktuell' uebersetzt'?
Da sollte wirklich "konkret" stehen ... (Seite 8, wo es
um Parameter geht.)
Nein, es ging um Datumse, "getActualYear liefert das aktuelle Jahr",
grob zitiert. Nicht wirklich ein Problem, springt halt ins Auge.
Post by Paul Ebermann
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
Hmm, finde ich gerade nicht.
Unter "Haben Objekte auch einen Namen" oder so aehnlich, wenn ich mich
recht erinnere.
Post by Paul Ebermann
(Allerdings habe ich gerade auf Seite 9 bei der Verwendung
von new zwei Fehler gefunden - Person ist doch kein Subtyp von
String (es sei denn, du hast String gehackt, oder verwendest
eine eigene Klasse dieses Namens, was ich fuer eine FAQ, in
der es nicht um dieses Thema geht, sehr verwirrend faende).
Ja, und spaeter gibt's noch ein Listing wo zwei Variablen mit Namen "m"
im gleichen Block benutzt werden, aber das hab' ich als simplen Typo
gebucht, dass da wirklich ein Verstaendnissproblem dahinter stand, war
ja eher unwahrscheinlich ;)
Post by Paul Ebermann
PS: Gerade bemerkt, dass ich etwas speat dran bin mit meiner
Antwort, und einige der Fehler schon korrigiert sind - aber
vielleicht hilft es ja trotzdem ...
Ach macht ja nichts. Ist ja eh nichts bahnbrechend wichtiges worum's
hier geht.
Michael Paap
2008-10-12 16:43:29 UTC
Permalink
Post by J. Stoever
for (Point p : points) { p.x = 10; }
hat eine direkte Wirkung auf die tatsaechlichen Elemente in points.
Wuerden die da kopiert werden, waere dem nicht so.
Es wir die Referenz kopiert. Genau wie bei der Übergabe "eines Objekts"
als Parameter eines Methodenaufrufs. Call by value, nur dass der "value"
eben eine Referenz ist.

Glaub mir das ruhig mal.
Post by J. Stoever
Ja, und spaeter gibt's noch ein Listing wo zwei Variablen mit Namen "m"
im gleichen Block benutzt werden, aber das hab' ich als simplen Typo
gebucht, dass da wirklich ein Verstaendnissproblem dahinter stand, war
ja eher unwahrscheinlich ;)
Korrigiert. Such ruhig weiter, ich bin dankbar.

Gruß,
Michael
J. Stoever
2008-10-12 17:30:53 UTC
Permalink
Post by Michael Paap
Es wir die Referenz kopiert. Genau wie bei der Übergabe "eines Objekts"
als Parameter eines Methodenaufrufs. Call by value, nur dass der "value"
eben eine Referenz ist.
Glaub mir das ruhig mal.
Das brauch' ich Dir nicht zu glauben, das weiss ich schon seit ca. 15
Jahren ;) Du hast aber selber geschrieben, dass die Elemente kopiert
werden. Und fang' jetzt bloss nicht davon an, dass Arrays eben immer nur
Pointer als Elemente haben koennen (abgesehen von primitives). Das ist
zwar technisch gesehen richtig, aber eben nicht im normalen Sprachgebrauch.

Ich wuerde vorschlagen, wir geben diesen Thread-Ast auf, und schreiben
in dem anderen weiter, dann muessen wir nicht dauernd alles zwei mal
schreiben ;)
Michael Paap
2008-10-12 18:31:21 UTC
Permalink
Post by J. Stoever
Das brauch' ich Dir nicht zu glauben, das weiss ich schon seit ca. 15
Jahren ;) Du hast aber selber geschrieben, dass die Elemente kopiert
werden. Und fang' jetzt bloss nicht davon an, dass Arrays eben immer nur
Pointer als Elemente haben koennen (abgesehen von primitives).
Genau so ist es aber nun mal.
Post by J. Stoever
Das ist
zwar technisch gesehen richtig, aber eben nicht im normalen Sprachgebrauch.
Der "normale Sprachgebrauch" ist mir ziemlich egal. Ich verwende bei
fachlichen Diskussionen Fachbegriffe, und das aus gutem Grund. Der Wert
einer Variablen eines Referenztyps ist eine Referenz, der einer
Variablen eiens Priomitivtyps ist eine Zahl, ein Zeichen oder ein
boolscher Wert. Was auch immer der Wert ist, genau dieser wird kopiert.

Auf diese Weise braucht man keine Unterscheidung zwischen Primitivtypen
und Refeenztypen und es ist völlig klar, dass eine Zuweisung nach außen
hin wirkungslos bleibt.

Alles andere ist bestenfalls komplizierter, meist aber schlicht falsch.
Post by J. Stoever
Ich wuerde vorschlagen, wir geben diesen Thread-Ast auf, und schreiben
in dem anderen weiter, dann muessen wir nicht dauernd alles zwei mal
schreiben ;)
Hm, sei mir nicht böse, aber ich werd gar nicht mehr viel dazu
schreiben. Ich bin nach acht Jahren dclj in Bezug auf das, was wir
gerade diskutieren, absolut nicht kompromisswillig. Mal ganz krass
gesagt: Entweder, du siehst ein, dass mein Sprachgebrauch bzgl. dessen,
was hier zur Diskussion steht, im Gegensatz zu deinem korrekt ist, oder
du lässt es halt bleiben.

Vielleicht reicht es dazu, zu merken, dass du hier mit dem, was du
verkaufen willst, sehr einsam sein wirst. ;-)

Ansonsten vielen Dank für deine Korrekturen!

Gruß,
Michael
J. Stoever
2008-10-12 19:52:56 UTC
Permalink
Post by Michael Paap
Post by J. Stoever
Das brauch' ich Dir nicht zu glauben, das weiss ich schon seit ca. 15
Jahren ;) Du hast aber selber geschrieben, dass die Elemente kopiert
werden. Und fang' jetzt bloss nicht davon an, dass Arrays eben immer nur
Pointer als Elemente haben koennen (abgesehen von primitives).
Genau so ist es aber nun mal.
So eine Sichtweise ist aber, imnsho, Bloedsinn. Arrays und Collections
in Java sind nicht typenlose Sammlungen von Pointern. Das mag zwar ein
Level tiefer so sein, aber wenn Du in diesen Bahnen denken willst,
solltest Du evtl. auf Assembler umsteigen. Und ein Point[] ist in Java
eben doch etwas anderes als ein String[]. Auch wenn es auf
Assembler-Level dann als das selbe raus kommt.
Post by Michael Paap
Post by J. Stoever
Das ist
zwar technisch gesehen richtig, aber eben nicht im normalen Sprachgebrauch.
Der "normale Sprachgebrauch" ist mir ziemlich egal. Ich verwende bei
fachlichen Diskussionen Fachbegriffe, und das aus gutem Grund. Der Wert
einer Variablen eines Referenztyps ist eine Referenz, der einer
Variablen eiens Priomitivtyps ist eine Zahl, ein Zeichen oder ein
boolscher Wert. Was auch immer der Wert ist, genau dieser wird kopiert.
Nur weil der Begriff technisch richtig ist, ist es kein Fachbegriff. Im
Gegenteil haben Fachbegriffe ueblicherweise sehr viel mehr an Bedeutung
als die blosse technische Bedeutung.

Wenn Du allen Ernstes behaupten willst, dass wenn Du schreibst "wir
kopieren ein Element eines JLabel-Arrays", Du damit meinst, den Pointer
zu kopieren, statt dass JLabel selbst zu kopieren, Du erwartest, dass
Leute das verstehen, dann ist diese Diskussion allerdings muessig.
Post by Michael Paap
Auf diese Weise braucht man keine Unterscheidung zwischen Primitivtypen
und Refeenztypen und es ist völlig klar, dass eine Zuweisung nach außen
hin wirkungslos bleibt.
Siehe anderes Post, eine Zuweisung bleibt zwar wirkungslos, aber das
heisst nicht, dass nichts nach aussen geht.
Post by Michael Paap
Post by J. Stoever
Ich wuerde vorschlagen, wir geben diesen Thread-Ast auf, und schreiben
in dem anderen weiter, dann muessen wir nicht dauernd alles zwei mal
schreiben ;)
Hm, sei mir nicht böse, aber ich werd gar nicht mehr viel dazu
schreiben. Ich bin nach acht Jahren dclj in Bezug auf das, was wir
gerade diskutieren, absolut nicht kompromisswillig. Mal ganz krass
gesagt: Entweder, du siehst ein, dass mein Sprachgebrauch bzgl. dessen,
was hier zur Diskussion steht, im Gegensatz zu deinem korrekt ist, oder
du lässt es halt bleiben.
Das ist ja dann ok. Wenn Du anerkennst, dass Du Dein Standpunkt
argumentativ nicht halten kannst oder willst, und dass Du einfach sagst
"Ich habe recht, bewiesen dadurch, dass ich es sage", dann kann ich das
einfach unter verschrobenem Bloedsinn abhaken.
Post by Michael Paap
Vielleicht reicht es dazu, zu merken, dass du hier mit dem, was du
verkaufen willst, sehr einsam sein wirst. ;-)
Das heisst ja nicht viel. Ich weiss nicht, ob Leute hier wirklich
glauben, dass "ein Element kopieren" bedeuten soll, einen zweiten
Pointer auf das Element zu setzen, oder das ein Element in einem
String-Array ein Pointer sein soll (etwas, das es in Java nicht mal in
der Form gibt), aber so oder so aendert das nichts am Rest der Welt. Und
da habe ich so eine verrueckte Definition noch nie gehoert, nicht mal
bei hardcore-c-fanatikern.

Nicht das ich glaube, dass Du das wirklich machen wuerdest, aber frag'
doch mal Deine Studenten oder Schueler, was sie unter "Ein Element eines
Point-Arrays kopieren" verstehen.
Bernd Eckenfels
2008-10-12 20:16:33 UTC
Permalink
Post by J. Stoever
So eine Sichtweise ist aber, imnsho, Bloedsinn. Arrays und Collections
in Java sind nicht typenlose Sammlungen von Pointern. Das mag zwar ein
Level tiefer so sein, aber wenn Du in diesen Bahnen denken willst,
solltest Du evtl. auf Assembler umsteigen. Und ein Point[] ist in Java
eben doch etwas anderes als ein String[]. Auch wenn es auf
Assembler-Level dann als das selbe raus kommt.
Und auf Bytecode...
Post by J. Stoever
Wenn Du allen Ernstes behaupten willst, dass wenn Du schreibst "wir
kopieren ein Element eines JLabel-Arrays", Du damit meinst, den Pointer
zu kopieren, statt dass JLabel selbst zu kopieren, Du erwartest, dass
Leute das verstehen, dann ist diese Diskussion allerdings muessig.
Man kann auch einfach beides schreiben, erst den terminus technicus, und
daraufhin ein NB: Im Falle von Objekten heisst dies, dass die Referenz auf
das Objekt kopiert wird.

Diese Art der Dokumentation ist in einem FAQ am geschicktesten, weil es
keine verwirrenden vereinfachungen enthaelt und trotzdem verstaendlich ist.
Post by J. Stoever
Das ist ja dann ok. Wenn Du anerkennst, dass Du Dein Standpunkt
argumentativ nicht halten kannst
Dein Standpunkt steht noch nicht mal..
Post by J. Stoever
Das heisst ja nicht viel. Ich weiss nicht, ob Leute hier wirklich
glauben, dass "ein Element kopieren" bedeuten soll, einen zweiten
Pointer auf das Element zu setzen, oder das ein Element in einem
String-Array ein Pointer sein soll (etwas, das es in Java nicht mal in
der Form gibt)
Wenn es keine Pointer in Java gibt, dann nenn sie nicht so. Es sind
referenzen, und die kann man sehr wohl kopieren und zeigen dann auf
bestehende Objekte. (Ja in der Hinsicht verhalten sie sich ganz genau wie
Pointer)
Post by J. Stoever
Nicht das ich glaube, dass Du das wirklich machen wuerdest, aber frag'
doch mal Deine Studenten oder Schueler, was sie unter "Ein Element eines
Point-Arrays kopieren" verstehen.
Element ist in dem Zusammenhang Java allerdings auch falsch:

JLS> An array object contains a number of variables. The number of variables
may be zero, in which case the array is said to be empty. The variables
contained in an array have no names; instead they are referenced by array
access expressions that use nonnegative integer index values. These
variables are called the components of the array. If an array has n
components, we say n is the length of the array; the components of the array
are referenced using integer indices from 0 to n - 1, inclusive.

Gruss
Bernd
Stefan Ram
2008-10-12 21:24:31 UTC
Permalink
Post by Bernd Eckenfels
Wenn es keine Pointer in Java gibt, dann nenn sie nicht so.
Wenn Du dir das Zitat mit den »components« vielleicht damals
gemerkt hast also ich es 2006 in

<array-***@ram.dialup.fu-berlin.de>

hier schrieb, dann könntest Du und der Vorposter euch auch
noch folgendes merken:

»(...) reference values (...) are pointers«

JLS3, 4.3.1.

http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.1
Paul Ebermann
2008-10-12 22:54:45 UTC
Permalink
Post by Bernd Eckenfels
Post by J. Stoever
Das heisst ja nicht viel. Ich weiss nicht, ob Leute hier wirklich
glauben, dass "ein Element kopieren" bedeuten soll, einen zweiten
Pointer auf das Element zu setzen, oder das ein Element in einem
String-Array ein Pointer sein soll (etwas, das es in Java nicht mal in
der Form gibt)
Wenn es keine Pointer in Java gibt, dann nenn sie nicht so. Es sind
referenzen, und die kann man sehr wohl kopieren und zeigen dann auf
bestehende Objekte. (Ja in der Hinsicht verhalten sie sich ganz genau wie
Pointer)
Das Problem ist, dass es in einer der verwandten Sprachen
(C++) sowohl Pointer als auch Referenzen gibt, und das,
was Java verwendet, eigentlich mehr den Pointern entspricht,
auch wenn es haeufig als Referenzen bezeichnet wird.

Genaugenommen gibt es in Java _nur_ Pointer (wenn
man man von den primitiven Typen absieht [1]), wobei
man mit ihnen aber keine Zeigerarithmetik machen
kann, und auch nicht einfach zu einem Typ einen
passenden Zeigertyp bilden kann, weil unsere Zeiger
immer nur Zeiger auf Objekte sind.

Paul

[1] Wenn man es etwas philosophischer betrachtet, kann man
auch die Werte der primitiven Typen als Zeiger auf
geeignete immutable-Objekte auffassen.
Aber wir muessen diese Diskussion nicht schon wieder
aufwaermen, da ich offenbar der einzige hier bin, der
den Standpunkt vertritt.
--
Nun ludigxas: : ()
Stefan Ram
2008-10-13 00:48:23 UTC
Permalink
Post by Paul Ebermann
[1] Wenn man es etwas philosophischer betrachtet, kann man
auch die Werte der primitiven Typen als Zeiger auf
geeignete immutable-Objekte auffassen.
Dies ist weniger eine Frage der Philosophie als
der Terminologie.

Offensichtlich ist die Auffassung [1] nicht mit der
JLS-Terminologie verträglich.

Genauso offensichtlich kann man eine Terminologie
konstruieren, mit der sie verträglich ist. (Falls ich
keine Inkonsistenz in [1] übersehen habe.)

Umso mehr Deine Terminologie vom üblichen Sprachgebrauch
abweicht, um so mehr Vorteile muß sie bieten, um diesen
Makel wieder aufzuwiegen.

Allerdings bietet sich meiner Meinung nach eher der
Wertebegriff als Oberbegriff für Werte und Zeiger an als der
Zeigerbegriff. Referenzen und primitive Werte sind eben beides
Werte.

Für mich ist »Wert« nur ein Synonym für »Entität«, also etwas
das existiert. Die Existenz einer Sache ist eine Frage der
(konsistenten) Vereinbarung und bedeutet dann, daß man
von dieser Sache in Aussagen sprechen kann - bzw. in der
Programmierung: Daß man sie als Argument oder Operand in
Ausdrücken verwenden kann. (Dabei werden sie selber auch
wieder jeweils durch einen Ausdruck angegeben.)

Ein reiner Wertausdruck ist ein Teil des Quelltextmodells,
der einen Wert des Laufzeitmodells bei einer späteren
Ausführung des Quelltextes angibt.

Werte können axiomatisch eingeführt werden, wie etwa die leere
Menge in der ZF-Mengenlehre. Beispielsweise:

1. Axiom: Es gibt 0.
2. Axiom: Es gibt 1.
3. Axiom: 0 ist nicht gleich 1.

Außerdem braucht man bei Anwendungen meist noch eine formale
Sprache, mit der man die Werte, deren Existenz durch das
Axiomsystem gesichert ist, angeben kann. (Das gelingt aber
nicht immer ganz: Man kann zwar die Existenz der reellen
Zahlen axiomatisch sicherstellen, aber keine endliche
Zeichenfolge über einem endlichen Alphabet für jede reelle
Zahl angeben.)

In dem obigen Axiomensystem geben die Axiome bereits diese
Sprache an, die Sprache ist nämlich {"0","1"} mit der Semantik
{("0",0),("1",1)}.

Stepanov versucht sich derzeit in den Abschnitten 1.1 und 1.2
des folgenden Entwurfs an programmiersprachenunabhängigen
Definitionen der folgenden Begriffe für die Anwendung in der
Programmierung.

- »ideal entity«
- »real entity«
- »ideal genus«
- »entity«
- »value type«
- »value«

http://www.stepanovpapers.com/eop/eop.pdf
http://google.to/search?q=cache:www.stepanovpapers.com/eop/eop.pdf

Allerdings kenne ich diesen Text nicht gut genug, um ihn
zu bewerten. Ich hatte nur vor kurzem davon gehört.
Stefan Ram
2008-10-13 22:49:25 UTC
Permalink
Post by Stefan Ram
Allerdings bietet sich meiner Meinung nach eher der
Wertebegriff als Oberbegriff für Werte und Zeiger an als der
Zeigerbegriff. Referenzen und primitive Werte sind eben beides
Werte.
Vielleicht meint Paul ja folgendes:

In dem Term »0+0« kommt der Wert »0« zweimal vor.
Da es nur eine Null gibt, kann sie nicht links und
rechts vom »+«-Zeichen gleichzeitig stehen.
Daher muß man die beiden »0« als »Referenzen« auf den
Wert 0 ansehen.

Hier kommt die Art, wie sich Nominalphrasen einer Sprache
auf ihre Objekte beziehen zum Ausdruck.

Die genaue Art der Herstellung dieser Referenz ist
tatsächlich ein offenes Problem, dessen Diskussion man
tatsächlich zur Philosophie zählt. Ich denke etwa an

http://google.to/search?q=Quine+Inscrutability

.
Paul Ebermann
2008-10-18 11:42:57 UTC
Permalink
Post by Stefan Ram
Post by Stefan Ram
Allerdings bietet sich meiner Meinung nach eher der
Wertebegriff als Oberbegriff für Werte und Zeiger an als der
Zeigerbegriff. Referenzen und primitive Werte sind eben beides
Werte.
In dem Term »0+0« kommt der Wert »0« zweimal vor.
Da es nur eine Null gibt, kann sie nicht links und
rechts vom »+«-Zeichen gleichzeitig stehen.
Daher muß man die beiden »0« als »Referenzen« auf den
Wert 0 ansehen.
Hmm, das Zeichen »0« sehe ich als Literal fuer eine
solche Referenz an.

Genau wie bei »"a" + "a"« auf beiden Seiten des »+«-Zeichens
zwei identische String-Literale stehen, die daher (modulo
Konstanten-Zusammenfassung zur Compile-Zeit) fuer zwei
Referenzen auf das selbe String-Objekt stehen.


Paul
--
Die dclj-FAQ wird immer freitags hier gepostet.
Eine (nicht ganz aktuelle) HTML-Version gibt es hier:
http://de.geocities.com/uweplonus/faq/
Michael Paap
2008-10-13 11:27:53 UTC
Permalink
Post by Paul Ebermann
[1] Wenn man es etwas philosophischer betrachtet, kann man
auch die Werte der primitiven Typen als Zeiger auf
geeignete immutable-Objekte auffassen.
Aber wir muessen diese Diskussion nicht schon wieder
aufwaermen, da ich offenbar der einzige hier bin, der
den Standpunkt vertritt.
Sagen wir so: Ich kann den Standpunkt verstehen, aber ich sehe nicht,
inwieweit dieser Ansatz zu einer einfacheren oder schlüssigeren
Sichtweise des Verhaltens von Java führt. Insofern finde ich diese Art
von philosophischer Betrachtungsweise nicht sonderlich reizvoll, obwohl
ich fürs Philosophische prinzipiell zu haben bin.

Gruß,
Michael
Michael Paap
2008-10-13 04:47:55 UTC
Permalink
Post by J. Stoever
So eine Sichtweise ist aber, imnsho, Bloedsinn. Arrays und Collections
in Java sind nicht typenlose Sammlungen von Pointern. Das mag zwar ein
Level tiefer so sein, aber wenn Du in diesen Bahnen denken willst,
solltest Du evtl. auf Assembler umsteigen. Und ein Point[] ist in Java
eben doch etwas anderes als ein String[]. Auch wenn es auf
Assembler-Level dann als das selbe raus kommt.
Gibts eigentlich schon ein Law, nach dem jemand, der in einer
OOP-Diskussion mit Assembler daherkommt, automatisch verloren hat?
Post by J. Stoever
Wenn Du allen Ernstes behaupten willst, dass wenn Du schreibst "wir
kopieren ein Element eines JLabel-Arrays", Du damit meinst, den Pointer
zu kopieren, statt dass JLabel selbst zu kopieren, Du erwartest, dass
Leute das verstehen, dann ist diese Diskussion allerdings muessig.
Die ist müssig, weil du nicht verstehen willst, worum es eigentlich
geht. Aber das macht nichts. Hier finden sich nette Menschen, die es dir
erklären. Du könntest natürlich auch Google-Groups bemühen...
Post by J. Stoever
Das ist ja dann ok. Wenn Du anerkennst, dass Du Dein Standpunkt
argumentativ nicht halten kannst oder willst, und dass Du einfach sagst
"Ich habe recht, bewiesen dadurch, dass ich es sage", dann kann ich das
einfach unter verschrobenem Bloedsinn abhaken.
Ja. Schatzi. Ganz wie du sagst. *g*
Post by J. Stoever
Das heisst ja nicht viel. Ich weiss nicht, ob Leute hier wirklich
glauben, dass "ein Element kopieren" bedeuten soll, einen zweiten
Pointer auf das Element zu setzen, oder das ein Element in einem
String-Array ein Pointer sein soll (etwas, das es in Java nicht mal in
der Form gibt)
Den Begriff "Pointer" hast du angeschleppt. Ich verwende ihn von mir aus
aus gutem Grund nicht.

Natürlich kannst du Objekte kopieren. Aber bei der foreach-Schleife
werden - ebenso wie bei der Parameter-Übergabe - eben *keine* Objekte
kopiert, sondern Werte von Variablen. Und das sind bei Variablen eines
Refernztyps nun mal Referenzen, was jedem klar ist, der mal eine dieser
CbV/CbR-Diskussionen mitbekommen hat, die hier immer wieder von
Neueinsteigern losgetreten werden.
Post by J. Stoever
aber so oder so aendert das nichts am Rest der Welt. Und
da habe ich so eine verrueckte Definition noch nie gehoert, nicht mal
bei hardcore-c-fanatikern.
Was zeigt, dass du entweder noch nicht lange hinhörst oder lernresistent
bist.
Post by J. Stoever
Nicht das ich glaube, dass Du das wirklich machen wuerdest, aber frag'
doch mal Deine Studenten oder Schueler, was sie unter "Ein Element eines
Point-Arrays kopieren" verstehen.
Ich lebe derzeit davon, dass ich ständig genau solche Fragen stelle und
ggf. Erläuterungen nachliefere. Mach dir um mich und meine "Schüler" mal
keine Sorgen. Die mögen mich und ich mag sie.

Nun hab ich dir doch wieder geantwortet... aber nun auch wirklich
letztmalig. Du wirst vermutlich noch ein wenig herummaulen und in einer
Woche wird man hier nichts mehr von dir hören. Ist ja auch richtig so...
hier tummeln sich ja offensichtlich Leute, die keine Ahnung haben, gell? *g*

Machs gut.

Gruß,
Michael
Michael Paap
2008-10-12 16:34:32 UTC
Permalink
Post by Paul Ebermann
(Allerdings habe ich gerade auf Seite 9 bei der Verwendung
von new zwei Fehler gefunden - Person ist doch kein Subtyp von
String (es sei denn, du hast String gehackt, oder verwendest
eine eigene Klasse dieses Namens, was ich fuer eine FAQ, in
der es nicht um dieses Thema geht, sehr verwirrend faende).
Ups. Danke. Schludrigkeit.

Gruß,
Michael
Bernd Eckenfels
2008-10-12 20:26:55 UTC
Permalink
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
new Object().toString();

Gruss
Bernd
J. Stoever
2008-10-12 20:43:11 UTC
Permalink
Post by Bernd Eckenfels
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
new Object().toString();
Ja, und jetzt zeig mir mal wie das mit zwei Ausdruecken in einer Zeile
funktioniert.
Bernd Eckenfels
2008-10-12 20:46:49 UTC
Permalink
Post by J. Stoever
Post by Bernd Eckenfels
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
new Object().toString();
Ja, und jetzt zeig mir mal wie das mit zwei Ausdruecken in einer Zeile
funktioniert.
Ohne Zuweisung hat man in der selben Zeile Zugriff. Von "2 Ausdrücken" stand
da nichts. Es ist also nicht falsch.

Gruss
Bernd
J. Stoever
2008-10-12 20:52:52 UTC
Permalink
Post by Bernd Eckenfels
Post by J. Stoever
Post by Bernd Eckenfels
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
new Object().toString();
Ja, und jetzt zeig mir mal wie das mit zwei Ausdruecken in einer Zeile
funktioniert.
Ohne Zuweisung hat man in der selben Zeile Zugriff. Von "2 Ausdrücken" stand
da nichts. Es ist also nicht falsch.
Genau. In einer Zeile kann man aber mehr als einen Ausdruck haben, genau
so wie man einen Ausdruck auf mehrere Zeilen dehnen kann. Das Wort
"Zeile" ist also falsch, da die Moeglichkeit, auf das Objekt
zuzugreifen, nichts mit der Zeile zu tun hat.

Beispiel:

new Object()
.toString();

Zwei Zeilen, trotzdem kann man drauf zugreifen.

new Object().toString(); .clone();

Eine Zeile, trotzdem kann das .clone nicht drauf zugreifen. Ergo ist
"Zeile" als Limitierung unsinnig und falsch.
Bernd Eckenfels
2008-10-12 21:05:08 UTC
Permalink
Post by J. Stoever
Genau. In einer Zeile kann man aber mehr als einen Ausdruck haben, genau
so wie man einen Ausdruck auf mehrere Zeilen dehnen kann. Das Wort
"Zeile" ist also falsch, da die Moeglichkeit, auf das Objekt
zuzugreifen, nichts mit der Zeile zu tun hat.
new Object()
.toString();
Zwei Zeilen, trotzdem kann man drauf zugreifen.
Wenn A->B gegeben ist ist damit noch lange nicht !B->A gegeben.

Gruss
Bernd
J. Stoever
2008-10-12 21:41:02 UTC
Permalink
Post by Bernd Eckenfels
Post by J. Stoever
Genau. In einer Zeile kann man aber mehr als einen Ausdruck haben, genau
so wie man einen Ausdruck auf mehrere Zeilen dehnen kann. Das Wort
"Zeile" ist also falsch, da die Moeglichkeit, auf das Objekt
zuzugreifen, nichts mit der Zeile zu tun hat.
new Object()
.toString();
Zwei Zeilen, trotzdem kann man drauf zugreifen.
Wenn A->B gegeben ist ist damit noch lange nicht !B->A gegeben.
Praktisch, dass Du meinen Beweis, dass A->B *NICHT* gegeben ist,
zufaellig beim Quoten vergessen hast.

Mein Punkt ist, und ich kann nicht glauben dass ich das so oft
wiederholen muss, dass eine Zeile kein sinnvolles oder auch nur
korrektes Limit fuer Objektzugriff ist. Weder haengt die Moeglichkeit,
auf ein Objekt zuzugreifen, von der Zeilenanzahl ab, noch ist eine Zeile
etwas, das auf irgend eine Art und Weise die Funktion von Java-Code
erlauben oder beeintraechtigen kann.

Die Aussage, dass man auf ein Objekt noch zugreifen kann, solange man in
der selben Zeile ist, ist damit falsch, irrefuehrend und grundsaetzlich
unsinnig - man koennte ja einfach sein gesamtes Programm in eine Zeile
packen.

Das Original-Zitat war:

"Wenn man die Referenz auf das neu erzeugte Objekt keiner Variablen
zuweist, dann wird man später keinen Zugriff mehr auf das Objekt haben.
Man kann aber immerhin noch in der gleichen Zeile auf das Objekt zugreifen."

Der zweite Satz ist schlicht falsch. Mein zweites Beispiel zwei Posts
weiter oben beweist das. Ende.

Da ich nicht glauben kann, das jemand der intelligent genug ist, in
einer Newsgroup zum Thema Programmiersprachen zu posten, daemlich genug
sein koennte, um sowas laecherliches ueberhaupt noch weiter anzufechten,
gehe ich mal davon aus, dass das ganze gelangweilte Trollversuche sind,
und ziehe mich an dieser Stelle zurueck. Dito fuer Stefan Ram's Antwort,
die ebensowenig Sinn macht.
Bernd Eckenfels
2008-10-12 21:48:06 UTC
Permalink
Post by J. Stoever
Post by Bernd Eckenfels
Post by J. Stoever
Genau. In einer Zeile kann man aber mehr als einen Ausdruck haben, genau
so wie man einen Ausdruck auf mehrere Zeilen dehnen kann. Das Wort
"Zeile" ist also falsch, da die Moeglichkeit, auf das Objekt
zuzugreifen, nichts mit der Zeile zu tun hat.
new Object()
.toString();
Zwei Zeilen, trotzdem kann man drauf zugreifen.
Wenn A->B gegeben ist ist damit noch lange nicht !B->A gegeben.
Praktisch, dass Du meinen Beweis, dass A->B *NICHT* gegeben ist,
zufaellig beim Quoten vergessen hast.
Die Aussage war: "ich kann innerhalb einer zeile ohne Zuweisung auf ein
gerade erzeugtes Objekt zugreifen" und diese aussage ist (Beweis durch
Beispiel:) nicht falsch.

Ansonsten stimme ich ja mit dir überein, die Aussage ist nicht sonderlich
wertvoll oder abschliessend, nichtsdestotrotz ist sie richtig.
Post by J. Stoever
Mein Punkt ist, und ich kann nicht glauben dass ich das so oft
wiederholen muss, dass eine Zeile kein sinnvolles oder auch nur
korrektes Limit fuer Objektzugriff ist.
Da hast du Recht, aber auf die Aussage habe ich mich nicht bezogen.
Post by J. Stoever
Die Aussage, dass man auf ein Objekt noch zugreifen kann, solange man in
der selben Zeile ist, ist damit falsch
Sie ist _nicht_ falsch.
Post by J. Stoever
irrefuehrend und grundsaetzlich
unsinnig
Sie ist nicht sehr hilfreich, aber richtig.

Gruss
Bernd
Michael Paap
2008-10-13 05:16:03 UTC
Permalink
Post by Bernd Eckenfels
Sie ist nicht sehr hilfreich, aber richtig.
In Anbetracht der Tatsache, dass der Sinn der Aussage war, hilfreich zu
sein, ist sie damit gewissermaßen falsch. *g*

Gruß,
Michael
Michael Paap
2008-10-13 05:14:45 UTC
Permalink
Post by J. Stoever
Mein Punkt ist, und ich kann nicht glauben dass ich das so oft
wiederholen muss, dass eine Zeile kein sinnvolles oder auch nur
korrektes Limit fuer Objektzugriff ist. Weder haengt die Moeglichkeit,
auf ein Objekt zuzugreifen, von der Zeilenanzahl ab, noch ist eine Zeile
etwas, das auf irgend eine Art und Weise die Funktion von Java-Code
erlauben oder beeintraechtigen kann.
Die Aussage, dass man auf ein Objekt noch zugreifen kann, solange man in
der selben Zeile ist, ist damit falsch, irrefuehrend und grundsaetzlich
unsinnig - man koennte ja einfach sein gesamtes Programm in eine Zeile
packen.
Nur zur Klarstellung: *Ich* hab's eingesehen und geändert. ;-)
Post by J. Stoever
Da ich nicht glauben kann, das jemand der intelligent genug ist, in
einer Newsgroup zum Thema Programmiersprachen zu posten, daemlich genug
sein koennte, um sowas laecherliches ueberhaupt noch weiter anzufechten,
gehe ich mal davon aus, dass das ganze gelangweilte Trollversuche sind,
und ziehe mich an dieser Stelle zurueck. Dito fuer Stefan Ram's Antwort,
die ebensowenig Sinn macht.
Eieieiei. Selbst schlägst du in einem deiner ersten Postings hier mit
"völliger Quatsch" auf eine Aussage los, nur weil du sie nicht
verstehst, und dann so sensibel... du hast Nerven.

Gruß,
Michael
Stefan Ram
2008-10-12 21:11:57 UTC
Permalink
Post by J. Stoever
Post by Bernd Eckenfels
new Object().toString();
Ja, und jetzt zeig mir mal wie das mit zwei
Ausdruecken in einer Zeile funktioniert.
Davon war ja zuvor nicht die Rede.

Außerdem sind dies bereits »zwei Ausdrücke in einer Zeile«:

1. Ausdruck: »new Object()«
2. Ausdruck: »new Object().toString()«
Michael Paap
2008-10-13 05:10:26 UTC
Permalink
Post by Bernd Eckenfels
Post by J. Stoever
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
new Object().toString();
J. hat da imho schon recht:

Eine *Zeile* ist ein ziemlich willkürliches Konstrukt und dem von dir
genannten Ausdruck tut es keinen Abbruch, wenn man ihn auf mehrere
Zeilen verteilt.

Insofern ist "Ausdruck" da einfach besser.

Gruß,
Michael
Michael Paap
2008-10-13 05:25:39 UTC
Permalink
Post by J. Stoever
Ich habe da auf ersten Blick mehrere Fehler gesehen, z.B. wird
behauptet, in einer for-each Schleife wuerde der jeweilige Wert in eine
lokale Variable kopiert (was natuerlich voelliger Quatsch ist, da wird
lediglich ein Pointer gesetzt), "aktuell" wird mit "actual" uebersetzt,
Verwechslung von Zeile und Ausdruck (z.B. wird behauptet, wenn man ein
Objekt mit new erzeugt, ohne es irgendwas zuzuweisen, haette man in der
selben Zeile trotzdem noch Zugriff, was falsch ist), etc.
Nachdem wir mit den drei von dir genannten Sachen durch sind bzw. die
Diskussion dazu von meiner Seite beendet ist: Dein "etc." deutet an,
dass du noch mehr gefunden hast, was du für falsch hältst. Von meiner
Seite aus: Immer her damit.

Gruß,
Michael
Mike Wesling
2008-10-12 16:15:05 UTC
Permalink
Post by Michael Paap
Post by Mike Wesling
Ich kann, wie in meinem OP beschrieben, z.B. alles in der Main-Methode
abhandeln oder das ganze natürlich etwas aufteilen in kleinere Einheiten
und dann nur noch in der main den "Workflow" für die Abarbeitung angeben.
Entsprechend kann es dann passieren, dass die zweite Methode in der
Aufrufreihenfolge mit Daten arbeiten soll, die die erste ermittelt hat.
Du denkst prozedural. Das ist dann ok, wenn es sich um die innersten
Details handelt, irgendwelche Berechnungen zum Beispiel. Aber eine Ebene
drüber hast du keine Daten *mit* denen eine Methode etwas macht, sondern
du hast Objekte, die Methoden haben, mit denen sie ihren Zustand ändern.
Mir geht es in diesem Posting nicht um die Kommunikation zwischen
verschiedenen Objekten, sondern eher um die Gestaltung einer einzelnen
Klasse. Daher kann der Eindruck einer Prozeduralen Sichtweise aufkommen.
Post by Michael Paap
Post by Mike Wesling
1) Wie gut ist der Stil, wenn ich Methoden habe, die ohne
Übergabe-/Rückgabeparameter sind und ihre Ergebnisse in eine
Klassenvariable schreiben?
Das kommt darauf an. Du denkst prozedural. Und meinst du wirklich eine
Klassenvariable? Oder redest du von Attributen von Objekten? Nehmen wir
an letzteres ist der Fall... ich halte nichts davon, wenn Dinge in
Attribute geschrieben werden, die nicht zum Zustand des Objekts gehören.
Nein, nicht von Klassenvariablen in dem Sinne, dass die Variablen in
einer Klasse statisch deklariert sind.

Ich rede von Attributen von Objekten.
Post by Michael Paap
Post by Mike Wesling
Zustand des Objektes ist gut gesagt. Wenn ich Klassen nur brauche, um
etwas zu erledigen, dann ist der konkrete Zustand eigentlich gar nicht
so von Bedeutung.
Du denkst prozedural. ;-)
Für bestimmte Anwendungsfälle mag das auch "im Großen" berechtigt sein.
Du siehst ein Programm vor dir, welches ziemlich linear irgendeinen Job
erledigt. Es gibt Daten und es gibt Prozeduren, welche diese Daten
benutzen. Es gibt irgendein "Main". Mit OOP hat das nicht viel zu tun.
Das ist nicht schlimmt, aber nach "gutem Stil" im Sinne von OOP braucht
du dann halt gar nicht erst zu fragen. *g*
Naja, oft macht man sich auf dem Papier Gedanken, wie man ein System
aufbauen könnte. Auf dieser Ebene wird aber dann nie über die "interne"
Gestaltung einer einzelnen Klasse geredet.

Man kann das natürlich jedem einzelnen Entwickler überlassen, was er für
einen Stil hat, aber es soll eben nacher auch in einer einzelnen
Quellcode-Datei nicht aussehen, wie Kraut und Rüben.
Post by Michael Paap
Was ist denn ein "Klassen-Objekt"? Ich glaube, wir sollten erst mal ein
paar Begriffe klären. Schau dir bitte mal aus
http://feu.mpaap.de/1618/faq.pdf den Abschnitt "Variable / Attribut /
Klassenattribut / lokale Variable" an, das könnte die Diskussion
einfacher machen.
Ist schon geklärt. Ich hab mich ungenau ausgedrückt.
Wanja Gayk
2008-10-18 00:06:12 UTC
Permalink
Mike Wesling said...
Post by Mike Wesling
1) Wie gut ist der Stil, wenn ich Methoden habe, die ohne
Übergabe-/Rückgabeparameter sind und ihre Ergebnisse in eine
Klassenvariable schreiben?
Ein Objekt sollte IMO so wening Status wie möglich haben, das macht es
leichter es im Zweifel Threadsafe zu machen und macht es auc hleichter
etwas zu refactorn, sowie dem Programmverlauf zu folgen.

In diesem Sinne also nicht:

@NotThreadSafe
class Foo{

private Bar bar;

public void do(){
doPart1();
doPart2();
doSomethingElse();
}

private void prepareBar(){
bar = new Bar();
//...
}

private void useBar(){
if(bar != null && bar.equals(..)){
//..
bar.doSomething();
}
}
//...
}

Sondern:

@ThreadSafe
class Foo{

public void do(){
useBar();
doSomethingElse();
}

private Bar prepareBar(){
Bar bar = new Bar();
//...
return bar;
}

private void useBar(){
prepareBar().doSomething();
//...
}
}
//...
}


oder (IMO noch besser):

@ThreadSafe
class Foo{

public void do(){
useBar(preparedBar());
doSomethingElse();
}

private Bar preparedBar(){
bar = new Bar();
//...
return bar;
}

private void useBar(final Bar bar){
bar.doSomething();
//...
}
}
//...
}

oder gar:

@ThreadSafe
class Foo{

public void do(){
useBar(prepareBar(new Bar()));
doSomethingElse();
}

private Bar prepareBar(return Bar bar){
//...
return bar;
}

private void useBar(final Bar bar){
bar.doSomething();
//...
}
}
//...
}

Die Threadsafen-Varianten sind allesamt schneller, beim Multithreaded
Zugriff als wenn man die erste Variante mit synchronized-statements
threadsafe machen wollte.

Die einfachtse Regel für Threadsafety heißt: hat dein Objekt keinen
State (auch nicht durch benutzte, andere Objekte), dann ist es
Threadsafe.
Post by Mike Wesling
2) Ist es überhaupt guter Stil, dass man alles, was man theoretisch an
Ort und Stelle in der Main ermitteln könnte, auf mehrere sehr kleine
Methoden aufteilt?
Ja. Man kann ja über Reflection sogar private Methoden per JUnit testen
und je weniger eine Methode macht, desto einfacher ist sie zu testen.
Und auch hier hast du mit Methoden, die keinen State erwarten einfach
weniger Mühe sie zu testen, vor allem, wenn die alle Paremeter bekommen,
statt sie sich holen zu müssen und ihre Ergebnisse entweder in einem
Parameterobjekt oder Rückgabeobjekt liefert, statt in eigenen
Attributen.
Post by Mike Wesling
Zustand des Objektes ist gut gesagt. Wenn ich Klassen nur brauche, um
etwas zu erledigen, dann ist der konkrete Zustand eigentlich gar nicht
so von Bedeutung. Wenn ich aber als Aufrufer weiter mit dem
Klassen-Objekt arbeiten muss, dann sind die Daten bzw. der konkrete
Zustand schon wichtiger.
Die Kunst besteht darin, so weing Zustand wie irgend möglich zu halten
und die verschiedenen Zustandsvariablen zu unabhängig von einander wie
nur möglich zu bekommen, sodass möglichst viel parallel laufen kann.

Den geringere Masse an verbliebenen Zuständen kann man besser threadsafe
machen. Hier hat dann auch der Compiler mehr Möglichkeiten mit
lockElision, Escape-Analysis und ähnlichen Optimierungs-Taktiken die
Anzahl der gehaltenen Locks zu minimieren, bzw. hast du auch weniger
lock-contentions.

Gruß,
-Wanja-
--
Klingon function calls do not have 'parameters', they have 'arguments' -
and they always win them.
[Nele Abels in dsg]
Mike Wesling
2008-10-19 08:02:13 UTC
Permalink
Post by Wanja Gayk
Post by Mike Wesling
1) Wie gut ist der Stil, wenn ich Methoden habe, die ohne
Übergabe-/Rückgabeparameter sind und ihre Ergebnisse in eine
Klassenvariable schreiben?
Ein Objekt sollte IMO so wening Status wie möglich haben, das macht es
leichter es im Zweifel Threadsafe zu machen und macht es auc hleichter
etwas zu refactorn, sowie dem Programmverlauf zu folgen.
[...]
Danke, das ist mal ein gutes Posting!
Post by Wanja Gayk
Post by Mike Wesling
2) Ist es überhaupt guter Stil, dass man alles, was man theoretisch an
Ort und Stelle in der Main ermitteln könnte, auf mehrere sehr kleine
Methoden aufteilt?
Ja. Man kann ja über Reflection sogar private Methoden per JUnit testen
und je weniger eine Methode macht, desto einfacher ist sie zu testen.
Und auch hier hast du mit Methoden, die keinen State erwarten einfach
weniger Mühe sie zu testen, vor allem, wenn die alle Paremeter bekommen,
statt sie sich holen zu müssen und ihre Ergebnisse entweder in einem
Parameterobjekt oder Rückgabeobjekt liefert, statt in eigenen
Attributen.
Für mich ist hier aber ein kleiner Haken ersichtlich. Es ist für mich
weniger performant, da gewisse Teile jedes mal ausgeführt werden,
anstatt diese Teile einmal auszuführen und dann in einer
Zustandsvariablen zu speichern.
Jochen Theodorou
2008-10-19 11:59:36 UTC
Permalink
Mike Wesling schrieb:
[...]
Post by Mike Wesling
Es ist für mich
weniger performant, da gewisse Teile jedes mal ausgeführt werden,
anstatt diese Teile einmal auszuführen und dann in einer
Zustandsvariablen zu speichern.
du musst aber auch ein wenig aufpassen. Hab lieber ein sauberes Design
ohne Klimmzüge für die Performance, von der du noch gar nicht weisst wie
sie sein wird, als ein verhunztes Design, dass man nichtmal mehr schief
angucken will und indem Refactorings nur noch grausam sind. Ist jetzt
natürlich überspitzt ausgedrückt, aber in der Regel ist es so, dass wenn
dein Design gut ist, die Entwicklungszeit wesentlich verkürzt wird. Und
danach schaut man meistens erst Details der Performance an, um dann
gezielt die Schwachpunkte zu optimieren. So manche Minioptimierung an
anderer Stelle trägt vielleicht sogar zu einer schlechteren Performance
bei, weil der JIT den Code nicht mehr "versteht". Auch ist ein
einfachere Code vorzuziehen, wenn er schnell genug ist.

Gruss theo
Michael Paap
2008-10-19 14:09:06 UTC
Permalink
Post by Wanja Gayk
Ein Objekt sollte IMO so wening Status wie möglich haben, das macht es
leichter es im Zweifel Threadsafe zu machen und macht es auc hleichter
etwas zu refactorn, sowie dem Programmverlauf zu folgen.
Prinzipiell sehe ich das ja auch so, aber mir graut, wenn ich mir
vorstelle, wie irgendwelche Anfänger nach dieser Regel das Design ihres
Programms vermurksen, indem sie um jeden Preis versuchen, Zustand zu
vermeiden, so wie eine Zeit lang ein Haufen Leute versucht hat, die
Erzeugung von Objekten zu vermeiden, weil das ja ach so teuer ist.

Gruß,
Michael

Michael Paap
2008-10-12 09:49:22 UTC
Permalink
Post by Mike Wesling
Das nächste betrifft Informationen, die immer wieder zwischen
verschiedenen Klassen geteilt werden müssen. Zum Beispiel kann es sein,
dass man sich einmal einen bestimmten Pfad zu einer Datei zusammenbauen
will und dann von mehreren Klassen aus auf diesen zugreift. Oder man
möchte Konstanten in mehreren Klassen verwenden. Baut Ihr Euch dazu dann
immer eine "Datenhaltungs-Klasse" über einen Singleton oder wie macht
Ihr das?
Je nachdem... Singleton, Monostate oder auch mal ein de-facto-Singleton,
also ein Objekt, von welchem zwar nur ein Exemplar existiert, das aber
kein wirkliches Singleton ist.

http://staff.cs.utu.fi/~jounsmed/doos_06/material/SingletonAndMonostate.pdf

Gruß,
Michael
J. Stoever
2008-10-12 13:00:45 UTC
Permalink
Post by Michael Paap
Je nachdem... Singleton, Monostate oder auch mal ein de-facto-Singleton,
also ein Objekt, von welchem zwar nur ein Exemplar existiert, das aber
kein wirkliches Singleton ist.
Monostates in Java habe ich nie wirklich verstanden. Wieso sollte man,
da doch alles sowieso static ist, ueberhaupt eine Instanz von einer
Monostate-Klasse erzeugen, statt einfach Klasse.FELD bzw
Klasse.METHODE() direkt anzusprechen ?
Michael Paap
2008-10-12 13:45:09 UTC
Permalink
Post by J. Stoever
Monostates in Java habe ich nie wirklich verstanden. Wieso sollte man,
da doch alles sowieso static ist, ueberhaupt eine Instanz von einer
Monostate-Klasse erzeugen, statt einfach Klasse.FELD bzw
Klasse.METHODE() direkt anzusprechen ?
Um später leichter ändern zu können, falls es sich herausstellt, dass es
doch mehrere *unterschiedliche* Exemplare der Klasse geben soll. Dann
muss man nur an dieser herumbasteln, nicht an allen, die auf Attribute
oder Methoden zugreifen.

Gruß,
Michael
Paul Ebermann
2008-10-12 14:48:26 UTC
Permalink
Post by J. Stoever
Post by Michael Paap
Je nachdem... Singleton, Monostate oder auch mal ein de-facto-Singleton,
also ein Objekt, von welchem zwar nur ein Exemplar existiert, das aber
kein wirkliches Singleton ist.
Monostates in Java habe ich nie wirklich verstanden. Wieso sollte man,
da doch alles sowieso static ist, ueberhaupt eine Instanz von einer
Monostate-Klasse erzeugen, statt einfach Klasse.FELD bzw
Klasse.METHODE() direkt anzusprechen ?
So eine Klasse kann Interfaces implementieren, und damit
kann das Objekt an Methoden uebergeben werden, die nichts
von der konkreten Klasse wissen.

Oft gemacht fuer Benutzeroberflaechen, wo es z.B. genau ein
Objekt einer Unterklasse von (J)Frame gibt.


Paul
--
Ich beantworte Java-Fragen per E-Mail nur gegen Bezahlung. Kostenpunkt
100 Euro pro angefangene Stunde. Bitte erwähne in der Anfrage, dass du
das akzeptierst, da ich sonst die E-Mail einfach ignoriere.
(In der Newsgroup fragen ist billiger und oft auch schneller.)
J. Stoever
2008-10-12 12:58:52 UTC
Permalink
Post by Mike Wesling
Das nächste betrifft Informationen, die immer wieder zwischen
verschiedenen Klassen geteilt werden müssen. Zum Beispiel kann es sein,
dass man sich einmal einen bestimmten Pfad zu einer Datei zusammenbauen
will und dann von mehreren Klassen aus auf diesen zugreift. Oder man
möchte Konstanten in mehreren Klassen verwenden. Baut Ihr Euch dazu dann
immer eine "Datenhaltungs-Klasse" über einen Singleton oder wie macht
Ihr das?
Erstmal sollten natuerlich eigentlich nicht viele verschiedene Klassen
selber auf Dateien zugreifen, da waere es Design-technisch gesehen
besser, Du haettest eine Klasse, die die Datei liest, und wuerdest die
von den anderen Stellen aus ansprechen. Dann braeuchtest Du den Pfad
auch nur ein mal.

Generell aber macht man sich fuer sowas tatsaechlich eine
"Datenhaltungs-Klasse", und wenn man die dann noch "Settings" oder
aehnliches nennt, weiss man auch schon, was da hinein gehoert.

Ein Singleton allerdings sollte man daraus nicht machen, aus folgendem
Grund: Singletons sind dafuer da, den Zugriff auf limitierte Ressourcen
zu koordinieren, und nicht, um sie als "globale Variablen" zu
missbrauchen. Leute, die Singletons fuer "Klassen die man ueberall
braucht" benutzen, denken normalerweise ihr Design nicht durch, denn
eigentlich kann man so etwas auch problemlos als Parameter weitergeben.
m***@heinerkuecker.de
2008-10-14 22:33:19 UTC
Permalink
Post by Mike Wesling
Hallo,
Design im Betreff klingt vielleicht etwas übertrieben, aber ich will
einfach wissen, wie man gewisse Dinge Design-Technisch schön
implementiert. Vor allem, ob ihr einen Haufen (private) Methoden in
einer Klasse macht, obwohl diese nur 3-4 Zeilen haben, oder doch eher
versucht, mehr an einem Ort zu kapseln.
Das kommt ganz darauf an, welche Aufgabe man lösen will / muss.
Post by Mike Wesling
Ich habe festgestellt, dass es im Grunde die Möglichkeit gibt, den
ganzen Code auch sehr übersichtlich innerhalb eines Methodenrumpfes
abzuarbeiten.
Dann handlt es sich aber um ein ziemlich einfaches Programm.
Post by Mike Wesling
Die andere Variante wäre, verschiedene Bereiche daraus zu
machen und diese dann fast so "Workflow"-mässig in der vom User
public MyClass()
{
    Do_Part_1();
    ...
    Do_Part_10();
}
private void Do_Part_1()
{
    // do something here
}
So sollte man ein Programm aufbauen,
falls es solch einen einfachen Durchlauf
(so wie Du es Workflow nennst)
handelt.
Post by Mike Wesling
Wenn man das schön in Methoden aufteilt, dann kann es auch einige
Methoden geben, die z.B. Attribute für die weitere Verarbeitung
ermitteln. Andere Methoden brauchen diese dann, um ihre Arbeit
verrichten zu können.
Ja sicher, dies ist ein funktionaler Ansatz.
Post by Mike Wesling
Macht Ihr das so, dass es einen Klassenmember gibt (z.B. eine
Collection), der dann aber nicht wie bei public-Methoden als Parameter
übergeben wird? Also sprich, jede private Methode schreibt/liest ihre
private List MyList;
public MyClass()
{
    Do_Part_1();
    ...
    Do_Part_10();}
private void Do_Part_1()
{
    ... // Do something
    MyList.Add(my_information);}
private void Do_Part_1()
{
    ... // Read something from MyList
}
Ich lehne ein solches Design ab.

Falls Du die Gründe wiseen willst, so
suche mal bitte im Web nach 'Wikipedia Sideeffect'.

http://en.wikipedia.org/wiki/Side_effect_(computer_science)

Zitat:

Side effects often make a program's behavior more difficult to
predict.
A "Safe" operation is one that is guaranteed to be free of side-
effects...

Bei einem solchen Design arbeitet man also komplett
mit Seiteneffekten.

Prinzipiell ist es sicherer, keine Seiteneffekte zu verwenden.

Ausnahmen sind das Hinzufügen von Objekten zu einer
Struktur, zu einem Objekt-Graphen.

Ich habe aber vor einiger Zeit auch ein solches
Programm geschrieben, dass so wie Deine
Beschreibung oben aussah.

Es handelte sich um eine grosse aus einer
Datenbank gelesene Menge von Objekten,
in denen ich jeweils ein Flag als Seiteneffekt
gesetzt habe und die am Ende des Programms
je nach Kriterium verschieden gefiltert augegeben
wurden.

Also im Ausnahmefall kann man es auch so
lösen, wie Du beschrieben hast.
Post by Mike Wesling
Oder ist es besser, dass man jede private Methode eher gestaltet wie
eine public-Methode und gute Signaturen baut?
Gute Signaturen?
Leider ist das nicht ausagekräftig.
Post by Mike Wesling
Das würde dann aber auch
bedeuten, dass die private Methode "Do_Part_1()" einen Rückgabewert hat
private List MyList;
public MyClass()
{
    MyList = Do_Part_1();
    ...}
private List Do_Part_1()
{
    List InternalList;
    ... // Do something
    InternalList.Add(my_information);
    return InternalList;
}
Aha, also ohne Seiteneffekte.

So ist es in den meisten Fällen besser.
Man kann einfach Operationen Hinzufügen oder
Entfernen.

Jede Operation ist einzeln testbar.

Eine der Grundsätze der Informatik ist
die Beherrschung der Komplexität durch
Aufteilung einer komplexen Aufgabe in
weniger komplexe Teilaufgaben.

Noch viel schlechter als die erste Variante ist
das Arbeiten in geschachtelten Schleifen mit
eventuell mehreren verknüpften Operationen.

Dann wird der Code unwartbar.
Post by Mike Wesling
Das nächste betrifft Informationen, die immer wieder zwischen
verschiedenen Klassen geteilt werden müssen. Zum Beispiel kann es sein,
dass man sich einmal einen bestimmten Pfad zu einer Datei zusammenbauen
will und dann von mehreren Klassen aus auf diesen zugreift.
Eine Konfigurationsdatei ?
Post by Mike Wesling
Oder man
möchte Konstanten in mehreren Klassen verwenden. Baut Ihr Euch dazu dann
immer eine "Datenhaltungs-Klasse" über einen Singleton oder wie macht
Ihr das?
Die Konstanten könnten in einer zentralen Klasse liegen.

Für Konfigurationsdaten ist ein Singleton in Ordnung.

Prinzipiell kommt es auf den Scope an,
dazu ein Beispiel:

Man könnte in einer Applikaton den Mehrwertsteuersatz ändern.
Erfolgt die Änderung während einer offenen Transaktion,
führt dies zu einem Fehler.

Also benötigt jede Transaktion einen unveränderlichen
Mehrwertsteuersatz (oder Konfiguration oder
Geschäftsregel).

Prinzipiell gibt es in Java den lokalen Scope (Parameter und lokale
Variable), den globalen Scope (static) und den Heap (Objekte und
Member).

In Web-Applikationen gibt es noch die Session und den Page-Scope,
der Application-Scope ist global.

Dies kann nun weiter verfeinert werden, wie an es aktuell
am conversational scope in JSF sieht.
Post by Mike Wesling
Ich weiss nicht, aber bei guter Klassenaufteilung scheinen immer alle
Zugriffe gut aufzugehen, wie bei einem guten Schachspiel,
Ja, so sollte es sein.
Post by Mike Wesling
aber wenn das
nicht der Fall ist, dann fragt man sich immer, wie man jetzt die
Informationenen, die man in einer anderen Klasse schon einmal ermittelt
hat, nun in die jetzige Klasse rüber bekommt. Vielleicht könnt Ihr mir
da mal wieder ein bisschen helfen!?!?
Man muss sich an den Fachlichkeiten orientieren, die man
abbilden muss/will.
Also ein Kunde, Vertrag, Beleg, Buchung usw.

Am liebsten immutable, aber das geht nicht, falls
diese Datenstrukturen der Schnappschuss einer
Datenbank oder anderen persistenten Struktur sind
und ein Zurückschreiben geänderter Daten erfolgen
muss.

Eine Datenbankstruktur kann also schon vieles vorgeben.

Natürlich auch Constraints, zum Beispiel
Kardinalitäten.

Dann gibt es technisch notwendige Objekte wie
JFrame (Swing), Servlets, JSPs, EJBs usw.

Wichtig sind natürlich auch fachliche Operationen
(Actions, Commands).

Dies alles ein bisschen auf Pakete aufgeteilt und
dann schrittweise die Anforderungen eingebaut.

Das ist es so ziemlich.

Grüsse

Heiner

http://www.heinerkuecker.de/
http://www.sfcosmetics.de/
m***@heinerkuecker.de
2008-10-14 22:38:33 UTC
Permalink
Post by m***@heinerkuecker.de
Prinzipiell kommt es auf den Scope an,
Man könnte in einer Applikaton den Mehrwertsteuersatz ändern.
Man möchte in einer Applikation den Mehrwertsteuersatz
zur Laufzeit ändern können.
Post by m***@heinerkuecker.de
Erfolgt die Änderung während einer offenen Transaktion,
führt dies zu einem Fehler.
Grüsse

Heiner

http://www.heinerkuecker.de/
http://www.sfcosmetics.de/- Zitierten Text ausblenden -
Michael Paap
2008-10-15 07:56:16 UTC
Permalink
Post by m***@heinerkuecker.de
Aha, also ohne Seiteneffekte.
So ist es in den meisten Fällen besser.
Moment... du plädierst wirklich dafür, dass Methoden eines Objekts den
Zustand eben dieses Objekts nur ändern dürfen, wenn die zu ändernden
Attribute explizit übergeben werden?

Ich halte das für abwegig. Ja, "Seiteneffekte" sind problematisch. Aber
die Änderung eines Attributs durch eine Methode des betreffenden Objekts
ist für mich kein Seiteneffekt, sondern Ausdruck eines zentralen
Gedankens objektorientierter Programmierung.

Gruß,
Michael
m***@heinerkuecker.de
2008-10-15 17:40:56 UTC
Permalink
Post by Michael Paap
Post by m***@heinerkuecker.de
Aha, also ohne Seiteneffekte.
So ist es in den meisten Fällen besser.
Moment... du plädierst wirklich dafür, dass Methoden eines Objekts den
Zustand eben dieses Objekts nur ändern dürfen, wenn die zu ändernden
Attribute explizit übergeben werden?
Da hast Du mich falsch verstanden.
Änderung der Attribute sind Seiteneffekte.

Bei der Programmierung ohne Seiteneffekte werden keine
Attribute verändert, sondern es wird ein neues Objekt
oder ein Primitiv-Wert als Ergebnis zurückgegeben.
Post by Michael Paap
Ich halte das für abwegig. Ja, "Seiteneffekte" sind problematisch. Aber
die Änderung eines Attributs durch eine Methode des betreffenden Objekts
ist für mich kein Seiteneffekt, sondern Ausdruck eines zentralen
Gedankens objektorientierter Programmierung.
Das ist per Definition auch ein Seiteneffekt.
Hier wird aber die Kapselung eingehalten.

Wie ich aber schrieb, kann man nicht immer
ohne Seiteneffekte arbeiten
(keine Immutables).
Post by Michael Paap
Gruß,
Michael
Gruss
Heiner
Michael Paap
2008-10-15 18:10:46 UTC
Permalink
Post by m***@heinerkuecker.de
Da hast Du mich falsch verstanden.
Ja? Ich weiß nicht so recht. Immerhin kamen deine Empfehlungen in einem
Kontext, nämlich der Frage, ob es ok ist, aus einer Methode heraus
Attribute des Objekts zu manipulieren, ohne dass diese in der
Parameterliste stehen.

Für mich steht bei Java & Co das Objekt, in dem ich mich gerade befinde
mit seinem kompleten Zustand implizit *immer* in der Paramererliste.
Denn eben dies ist die Aufgabe von Methoden im OOP-Kontext: Sie dienen
dazu - in wohldefinierter Weise - auf den Objektzustand zuzugreifen.
Post by m***@heinerkuecker.de
Änderung der Attribute sind Seiteneffekte.
Für mich sind aufgrund der o.g. Sichtweise Änderungen der Attribute
eines Objekts über dessen Methoden keine Seiteneffekte.
Post by m***@heinerkuecker.de
Bei der Programmierung ohne Seiteneffekte werden keine
Attribute verändert, sondern es wird ein neues Objekt
oder ein Primitiv-Wert als Ergebnis zurückgegeben.
Post by Michael Paap
Ich halte das für abwegig. Ja, "Seiteneffekte" sind problematisch. Aber
die Änderung eines Attributs durch eine Methode des betreffenden Objekts
ist für mich kein Seiteneffekt, sondern Ausdruck eines zentralen
Gedankens objektorientierter Programmierung.
Das ist per Definition auch ein Seiteneffekt.
Hier wird aber die Kapselung eingehalten.
Wie ich aber schrieb, kann man nicht immer
ohne Seiteneffekte arbeiten
(keine Immutables).
Hm mir ist immer noch nicht klar, was du nun in dem Kontext, von dem wir
hier reden, sagen willst. Du plädierst gegen objektorientierte
Programmierung zugunsten einer eher funktionalen Vorgehensweise? Nichts
dagegen, aber dann doch vielleicht nicht in Java...?

Gruß,
Michael
Bernd Hohmann
2008-10-15 18:16:30 UTC
Permalink
Du plädierst gegen objektorientierte Programmierung zugunsten einer
eher funktionalen Vorgehensweise? Nichts dagegen, aber dann doch
vielleicht nicht in Java...?
Funktional oder Imperativ?

Bernd
Michael Paap
2008-10-15 18:49:55 UTC
Permalink
Post by Bernd Hohmann
Du plädierst gegen objektorientierte Programmierung zugunsten einer
eher funktionalen Vorgehensweise? Nichts dagegen, aber dann doch
vielleicht nicht in Java...?
Funktional oder Imperativ?
So richtig funktional irgendwie auch nicht. "Imperativ" passt hier imho
nicht, denn imperativ ist auch Java. Aber ich verstehe ja nicht so ganz,
worauf Heiner hinauswill. Das klingt ein bisschen so, als würde jemand,
der rein prozedural programmiert hat und sich da einen sauberen Stil -
keine Seiteneffekte - angewöhnt hat, das einfach 1:1 auf eine
objektorientierte Sprache übertragen.

Der wesentliche Unterschied zwischen einer rein prozeduralen und einer
objektorientierten Sichtweise ist aber für mich, dass bei letzterer eben
nicht Daten und Prozeduren getrennt vorliegen, sondern die Methoden zu
den Objekten gehören, weil sie eben der Mechanismus sind, der dazu
dient, dass man einem Objekt Nachrichten senden kann, die dessen Zustand
abfragen und beeinflussen.

Und damit ist für mich völlig klar, dass man die Änderung eines
Attributs aus einer Methode des Objekts heraus nicht mit den zu Recht
verpönten Seiteneffekten der prozeduralen Programmierung gleichsetzen kann.

Nicht umsonst spricht man bei dem Objekt, auf dem eine Methode
aufgerufen wurde, auch vom "impliziten Parameter": Das Objekt - und sein
in Form von Attributen vorliegender Zustand - ist für mich *immer*
impliziter Parameter eines Methodenaufruf und damit ist klar, dass ich
davon ausgehe, dass Methoden diesen Zustand ändern können.

Diese Sichtweise ist auch insofern konsequent, als ich bei einer
Methode, die eine Referenz auf ein *anderes* Objekt als Parameter hat,
ja auch dieses Objekt als Einheit sehe. Wenn ich die Referenz an eine
Methode übergebe, dann hat diese Zugriff auf die jeweilige Schnittstelle
des Objekts, d.h. ich muss damit rechnen, dass jeder Teil des
Objektzustandes, der über die Schnittstelle zugreifbar ist, durch die
Methode geändert wird. Man übergibt einer Methode ja eben nicht die
einzelnen Attribute eines weiteren Objekts, sondern eine Referenz auf
"das Objekt als Ganzes".

Und genau so sehe ich bei jeder Methode "this" als implizit übergeben
an, woraus zwanglos resultiert, dass ich aus einer Methode heraus
weitere Methoden des Objekts aufrufen und seine Attribute manipulieren darf.

Gruß,
Michael
Jochen Theodorou
2008-10-15 19:56:02 UTC
Permalink
Post by Michael Paap
Post by Bernd Hohmann
Du plädierst gegen objektorientierte Programmierung zugunsten einer
eher funktionalen Vorgehensweise? Nichts dagegen, aber dann doch
vielleicht nicht in Java...?
Funktional oder Imperativ?
So richtig funktional irgendwie auch nicht. "Imperativ" passt hier imho
nicht, denn imperativ ist auch Java. Aber ich verstehe ja nicht so ganz,
worauf Heiner hinauswill. Das klingt ein bisschen so, als würde jemand,
der rein prozedural programmiert hat und sich da einen sauberen Stil -
keine Seiteneffekte - angewöhnt hat, das einfach 1:1 auf eine
objektorientierte Sprache übertragen.
Der wesentliche Unterschied zwischen einer rein prozeduralen und einer
objektorientierten Sichtweise ist aber für mich, dass bei letzterer eben
nicht Daten und Prozeduren getrennt vorliegen, sondern die Methoden zu
den Objekten gehören, weil sie eben der Mechanismus sind, der dazu
dient, dass man einem Objekt Nachrichten senden kann, die dessen Zustand
abfragen und beeinflussen.
also ich weiss nicht wie es euch geht, aber mir scheint die Diskussion
ein bischen am Punkt vorbei zu gehen. Er hat ja mehrere Varianten
vorgestellt. Unter anderem eine in dem man Wrte, die für den nächsten
Methodenaufruf bestimmt sind im Zustand der Klasse, also den Attributen
speichert. Um ein dummes Beispiel zu geben:

class X {
private int transferData;
public boolean foo() {
transferData = 1;
t1();
t2();
return transferData==1
}
private void t1() { transferData++; }
private void t2(){ transferData--; }
}

so, was fällt auf? transferDatat wird nur zwischen foo, t1 und t2
benutzt. Die Lebenszeit dieser Information geht über die Aufrufdauer
dieser Methoden hinaus. Wann ist das also schlecht? Wenn transferData
kein primitive int ist, sondern vielleicht eine umfangreiche
Datenstruktur, denn dann kann der GC sie nicht einsammeln, weil man
irgendwo eine hard reference hat, die mit dem Zustand des Objektes
vielleicht garnichts zu tun hat. Schlecht ist es auch wenn foo parallel
aufgerufen wird... in beiden Fällen läßt sich leicht ein Beispiel
konstruieren in dem das schlecht ist.

Ist es dann überhaupt sinnvoll? Vielleicht, es könnte ja zum Beispiel
ein Cache sein. Vielleicht sind die Methoden, die damit arbeiten
zeitintensiv und man will deren Aufruf einsparen.

Dh, es kann sinnvoll sein, aber als grundsätzliches Muster halte ich es
für fragwürdig, dann doch lieber:

class X {
public boolean foo() {
int transferData = 1;
transferData = t1(transferData);
transferData = t2(transferData);
return transferData == 1
}
private int t1(int i) { return i+1;}
private int t2(int i) { return i-1;}
}

oder sogar:

class X {
private static class TransferData {
public TransferData(int i) {value=i;}
public int value;
}

public boolean foo() {
TransferData transferData = new TransferData(1);
t1(transferData);
t2(transferData);
return transferData.value == 1
}
private int t1(TransferData transferData) { transferData.value++;}
private int t2(TransferData transferData) { transferData.value--;}
}

Eine Lösung mit array wäre kürzer gewesen ;) In Java kommt das Problem
vielleicht ein bischen daher dass es keine out-Parameter gibt.
Andererseits stößt man in dieser Form eher selten auf das Problem finde ich.
Post by Michael Paap
Und damit ist für mich völlig klar, dass man die Änderung eines
Attributs aus einer Methode des Objekts heraus nicht mit den zu Recht
verpönten Seiteneffekten der prozeduralen Programmierung gleichsetzen kann.
womit man meist Dateizugriffe oder irgendwas mit dem Speicher meint.
Post by Michael Paap
Nicht umsonst spricht man bei dem Objekt, auf dem eine Methode
aufgerufen wurde, auch vom "impliziten Parameter": Das Objekt - und sein
in Form von Attributen vorliegender Zustand - ist für mich *immer*
impliziter Parameter eines Methodenaufruf und damit ist klar, dass ich
davon ausgehe, dass Methoden diesen Zustand ändern können.
also ich weiss von genug Sprachen wo man das sogar so direkt sehen kann,
aber wo spricht man denn vom "impliziten Parameter"? Ich dachte das
heisst "this" ;) und das "implizite this" ist dann der "implizit
implizite Parameter". Hehe, ok, lassen wird dass...

Gruss theo
Michael Paap
2008-10-15 21:21:10 UTC
Permalink
Post by Jochen Theodorou
also ich weiss nicht wie es euch geht, aber mir scheint die Diskussion
ein bischen am Punkt vorbei zu gehen. Er hat ja mehrere Varianten
vorgestellt. Unter anderem eine in dem man Wrte, die für den nächsten
Methodenaufruf bestimmt sind im Zustand der Klasse, also den Attributen
speichert.
Mich stört dieses "die für den nächsten Methodenaufruf bestimmt sind".
Ob etwas Teil des Objektzustandes ist, richtet sich nach anderen Kriterien.
Post by Jochen Theodorou
so, was fällt auf? transferDatat wird nur zwischen foo, t1 und t2
benutzt. Die Lebenszeit dieser Information geht
nicht?
Post by Jochen Theodorou
über die Aufrufdauer
dieser Methoden hinaus. Wann ist das also schlecht? Wenn transferData
kein primitive int ist, sondern vielleicht eine umfangreiche
Datenstruktur, denn dann kann der GC sie nicht einsammeln, weil man
irgendwo eine hard reference hat, die mit dem Zustand des Objektes
vielleicht garnichts zu tun hat. Schlecht ist es auch wenn foo parallel
aufgerufen wird... in beiden Fällen läßt sich leicht ein Beispiel
konstruieren in dem das schlecht ist.
Ich halte das schon alleine deshalb für schlecht, weil die Information
rein logisch eben *nicht* zum Zustand des Objekts gehört, sondern aus
fragwürdigen Gründen dort hingeräumt wurde.
Post by Jochen Theodorou
Post by Michael Paap
Und damit ist für mich völlig klar, dass man die Änderung eines
Attributs aus einer Methode des Objekts heraus nicht mit den zu Recht
verpönten Seiteneffekten der prozeduralen Programmierung gleichsetzen kann.
womit man meist Dateizugriffe oder irgendwas mit dem Speicher meint.
Nicht nur. Es gibt eine "Schule" prozeduraler Programmierung, die es
ablehnt, aus Prozeduren heraus *irgendwelche* mehr oder weniger globalen
Daten zu manipuilieren, wenn diese nicht als Parameter übergeben werden.
Die Vorteile liegen imho auf der Hand.
Post by Jochen Theodorou
also ich weiss von genug Sprachen wo man das sogar so direkt sehen kann,
aber wo spricht man denn vom "impliziten Parameter"?
Bei der Vermittlung von Konzepten objektorientierter Programmierung tut
man dies.
Post by Jochen Theodorou
Ich dachte das heisst "this" ;)
Das Schhlüsselwort "this" ist nur ein Weg, den impliziten Parameter
explizit anzusprechen.
Post by Jochen Theodorou
und das "implizite this" ist dann der "implizit
implizite Parameter". Hehe, ok, lassen wird dass...
Man spricht vom impliziten Parameter eines Methodenaufrufs, wenn man
verdeutlichen möchte, dass es neben den eigentlichen Parametern noch
etwas gibt, das "betroffen" ist. Oft wird dabei zur Erläuterung ein
Methodenaufruf als Funktion betrachtet, etwa

bla.foo(x, y)

als Funktion

f(bla, x, y).

Gruß,
Michael
Jochen Theodorou
2008-10-16 00:12:45 UTC
Permalink
Post by Michael Paap
Post by Jochen Theodorou
also ich weiss nicht wie es euch geht, aber mir scheint die Diskussion
ein bischen am Punkt vorbei zu gehen. Er hat ja mehrere Varianten
vorgestellt. Unter anderem eine in dem man Wrte, die für den nächsten
Methodenaufruf bestimmt sind im Zustand der Klasse, also den Attributen
speichert.
Mich stört dieses "die für den nächsten Methodenaufruf bestimmt sind".
Ob etwas Teil des Objektzustandes ist, richtet sich nach anderen Kriterien.
sehe ich ganz genauso, denn dafür gibt es ja Parameter. Aber darum geht
es nicht, es geht darum was der OP meinte ;)
Post by Michael Paap
Post by Jochen Theodorou
so, was fällt auf? transferDatat wird nur zwischen foo, t1 und t2
benutzt. Die Lebenszeit dieser Information geht
nicht?
Post by Jochen Theodorou
über die Aufrufdauer
dieser Methoden hinaus. Wann ist das also schlecht? Wenn transferData
kein primitive int ist, sondern vielleicht eine umfangreiche
Datenstruktur, denn dann kann der GC sie nicht einsammeln, weil man
irgendwo eine hard reference hat, die mit dem Zustand des Objektes
vielleicht garnichts zu tun hat. Schlecht ist es auch wenn foo parallel
aufgerufen wird... in beiden Fällen läßt sich leicht ein Beispiel
konstruieren in dem das schlecht ist.
Ich halte das schon alleine deshalb für schlecht, weil die Information
rein logisch eben *nicht* zum Zustand des Objekts gehört, sondern aus
fragwürdigen Gründen dort hingeräumt wurde.
ganz genau... und auf dem Level können Bernd und du sich sicher auch
einigen ;)
Post by Michael Paap
Post by Jochen Theodorou
Post by Michael Paap
Und damit ist für mich völlig klar, dass man die Änderung eines
Attributs aus einer Methode des Objekts heraus nicht mit den zu Recht
verpönten Seiteneffekten der prozeduralen Programmierung gleichsetzen kann.
womit man meist Dateizugriffe oder irgendwas mit dem Speicher meint.
Nicht nur. Es gibt eine "Schule" prozeduraler Programmierung, die es
ablehnt, aus Prozeduren heraus *irgendwelche* mehr oder weniger globalen
Daten zu manipuilieren, wenn diese nicht als Parameter übergeben werden.
Die Vorteile liegen imho auf der Hand.
yupp
Post by Michael Paap
Post by Jochen Theodorou
also ich weiss von genug Sprachen wo man das sogar so direkt sehen kann,
aber wo spricht man denn vom "impliziten Parameter"?
Bei der Vermittlung von Konzepten objektorientierter Programmierung tut
man dies.
kommt auf den Vermittler an denke ich.
Post by Michael Paap
Ich dachte das heisst "this" ;)
Das Schhlüsselwort "this" ist nur ein Weg, den impliziten Parameter
explizit anzusprechen.
denk dran, da ist ein Smily

Gruss theo
Michael Paap
2008-10-16 06:55:47 UTC
Permalink
Post by Jochen Theodorou
kommt auf den Vermittler an denke ich.
Klar. Sagen wir so: Mein Vermittler hat es getan. Und ich halte es für
sinnvoll, weil sich daran eingies gut erklären lässt.
Post by Jochen Theodorou
Post by Jochen Theodorou
Ich dachte das heisst "this" ;)
Das Schhlüsselwort "this" ist nur ein Weg, den impliziten Parameter
explizit anzusprechen.
denk dran, da ist ein Smily
Ja, den sah ich wohl. Aber da man bei diesen Smilies auch nie so genau
weiß, was deren Setzer nun wirklich meint, dachte ich, ich schreib noch
was zu "this".

Gruß,
Michael
Mike Wesling
2008-10-19 08:16:02 UTC
Permalink
Post by Jochen Theodorou
class X {
private int transferData;
public boolean foo() {
transferData = 1;
t1();
t2();
return transferData==1
}
private void t1() { transferData++; }
private void t2(){ transferData--; }
}
so, was fällt auf? transferDatat wird nur zwischen foo, t1 und t2
benutzt. Die Lebenszeit dieser Information geht über die Aufrufdauer
dieser Methoden hinaus. Wann ist das also schlecht? Wenn transferData
kein primitive int ist, sondern vielleicht eine umfangreiche
Datenstruktur, denn dann kann der GC sie nicht einsammeln, weil man
irgendwo eine hard reference hat, die mit dem Zustand des Objektes
vielleicht garnichts zu tun hat. Schlecht ist es auch wenn foo parallel
aufgerufen wird... in beiden Fällen läßt sich leicht ein Beispiel
konstruieren in dem das schlecht ist.
Ist es dann überhaupt sinnvoll? Vielleicht, es könnte ja zum Beispiel
ein Cache sein. Vielleicht sind die Methoden, die damit arbeiten
zeitintensiv und man will deren Aufruf einsparen.
*zeitintensiv* war für mich das Stichwort. Der Gedanke von mir war, dass
es einfach mehr Zeit kostet, wenn ich bestimmte Operationen jedes Mal
ausführe, anstatt dies einmal zu machen und dann in einer Variablen zu
speichern/referenzieren.
Post by Jochen Theodorou
Dh, es kann sinnvoll sein, aber als grundsätzliches Muster halte ich es
class X {
public boolean foo() {
int transferData = 1;
transferData = t1(transferData);
transferData = t2(transferData);
return transferData == 1
}
private int t1(int i) { return i+1;}
private int t2(int i) { return i-1;}
}
class X {
private static class TransferData {
public TransferData(int i) {value=i;}
public int value;
}
public boolean foo() {
TransferData transferData = new TransferData(1);
t1(transferData);
t2(transferData);
return transferData.value == 1
}
private int t1(TransferData transferData) { transferData.value++;}
private int t2(TransferData transferData) { transferData.value--;}
}
Okay, danke!
Jochen Theodorou
2008-10-19 11:53:54 UTC
Permalink
[...]
Post by Mike Wesling
*zeitintensiv* war für mich das Stichwort. Der Gedanke von mir war, dass
es einfach mehr Zeit kostet, wenn ich bestimmte Operationen jedes Mal
ausführe, anstatt dies einmal zu machen und dann in einer Variablen zu
speichern/referenzieren.
der Grundgedanke des Cache. Macht IMHO keinen echten Unterschied wo und
wie gespeichert wird.

Gruss theo
Jochen Theodorou
2008-10-15 18:27:08 UTC
Permalink
Post by m***@heinerkuecker.de
Post by Michael Paap
Post by m***@heinerkuecker.de
Aha, also ohne Seiteneffekte.
So ist es in den meisten Fällen besser.
Moment... du plädierst wirklich dafür, dass Methoden eines Objekts den
Zustand eben dieses Objekts nur ändern dürfen, wenn die zu ändernden
Attribute explizit übergeben werden?
Da hast Du mich falsch verstanden.
Änderung der Attribute sind Seiteneffekte.
sehe ich auch so
Post by m***@heinerkuecker.de
Bei der Programmierung ohne Seiteneffekte werden keine
Attribute verändert, sondern es wird ein neues Objekt
oder ein Primitiv-Wert als Ergebnis zurückgegeben.
streng genommen ist das Erzeugen eines neuen Objektes auch ein
Seiteneffekt. Es verbraucht ja Speicher. Streng genommen kann auch ein
Methodenaufruf ein Seiteneffekt sein, selbst wenn die Methode nicht
macht. Denn zumindest in Java wird dadurch ein stack frame gebraucht. Es
gibt andere Sprachen, die ohne Stack arbeiten, da ist das eventuell
anders... Natürlich kommt es darauf an wie fundamentalistisch man an die
Sache rangeht ;)

Gruss theo
Michael Paap
2008-10-15 18:55:59 UTC
Permalink
Post by Jochen Theodorou
streng genommen ist das Erzeugen eines neuen Objektes auch ein
Seiteneffekt. Es verbraucht ja Speicher. Streng genommen kann auch ein
Methodenaufruf ein Seiteneffekt sein, selbst wenn die Methode nicht
macht. Denn zumindest in Java wird dadurch ein stack frame gebraucht. Es
gibt andere Sprachen, die ohne Stack arbeiten, da ist das eventuell
anders... Natürlich kommt es darauf an wie fundamentalistisch man an die
Sache rangeht ;)
Wenn du dann quasi jeden Effekt eines Methodenaufruf als Seiteneffekt
ansiehst, ist das nur nicht sonderlich hilfreich, weil der Begriff damit
seine Bedeutung verliert.

Für meine Begriffe sollte man den Begriff des Seiteneffekts auf das
beschränken, was er in prozeduralen Sprachen meist meint, nämlich eine
Wirkung, die nicht aus der Schnittstellenbeschreibung der Prozedur
ableitbar ist.

Wie schon gesagt: Der implizite Parameter eines Methodenaufrufs *ist*
für mich (eben implizit) Teil der Schnittstellenbeschreibung.

Gruß,
Michael
Jochen Theodorou
2008-10-15 20:00:32 UTC
Permalink
Post by Michael Paap
Post by Jochen Theodorou
streng genommen ist das Erzeugen eines neuen Objektes auch ein
Seiteneffekt. Es verbraucht ja Speicher. Streng genommen kann auch ein
Methodenaufruf ein Seiteneffekt sein, selbst wenn die Methode nicht
macht. Denn zumindest in Java wird dadurch ein stack frame gebraucht. Es
gibt andere Sprachen, die ohne Stack arbeiten, da ist das eventuell
anders... Natürlich kommt es darauf an wie fundamentalistisch man an die
Sache rangeht ;)
Wenn du dann quasi jeden Effekt eines Methodenaufruf als Seiteneffekt
ansiehst, ist das nur nicht sonderlich hilfreich, weil der Begriff damit
seine Bedeutung verliert.
wenn ich eine Methode aufrufen kann ohne das ein solcher Stackframe
erzeugt wird, dann habe ich den entsprechenden Seiteneffekt ja auch
nicht. Dass das derzeit in Java nicht anders geht ist dabei
nebensächlich... außerdem Sprach ich ja davon, dass es darauf ankommt
wie fundamentalistisch man an die Sache rangeht. Kommt man aus einem
fundamentalischtischen Lager der Funktionalen Programmierung, kann man
diese Ansicht durchaus haben.
Post by Michael Paap
Für meine Begriffe sollte man den Begriff des Seiteneffekts auf das
beschränken, was er in prozeduralen Sprachen meist meint, nämlich eine
Wirkung, die nicht aus der Schnittstellenbeschreibung der Prozedur
ableitbar ist.
ich sprach nicht von prozeduralen Sprachen.
Post by Michael Paap
Wie schon gesagt: Der implizite Parameter eines Methodenaufrufs *ist*
für mich (eben implizit) Teil der Schnittstellenbeschreibung.
und davon schon garnicht. Ich kann akzeptieren, dass du das Ändern eines
Attributes nicht als Seiteneffekt siehst. Es hat dann halt nur absolut
garnichts mit meinem Begriff für Seiteneffekt zu tun.

Gruss theo
Michael Paap
2008-10-15 21:25:43 UTC
Permalink
Ich kann akzeptieren, dass du das Ändern eines Attributes nicht als
Seiteneffekt siehst. Es hat dann halt nur absolut garnichts mit
meinem Begriff für Seiteneffekt zu tun.
Den Eindruck habe ich auch, ja. Ist ja auch nicht schlimm, aber was
bitte hat dein Begriff von Seiteneffekt mit dem zu tun, was Heiner
Kücker als Antwort auf Mike Wesling schrieb? *g*

Wir philosophieren hier ja nicht im luftleeren Raum über Seiteneffekte,
zumindest hatte ich nicht die Absicht. ;-)

Gruß,
Michael
Jochen Theodorou
2008-10-16 00:14:01 UTC
Permalink
Post by Michael Paap
Ich kann akzeptieren, dass du das Ändern eines Attributes nicht als
Seiteneffekt siehst. Es hat dann halt nur absolut garnichts mit
meinem Begriff für Seiteneffekt zu tun.
Den Eindruck habe ich auch, ja. Ist ja auch nicht schlimm, aber was
bitte hat dein Begriff von Seiteneffekt mit dem zu tun, was Heiner
Kücker als Antwort auf Mike Wesling schrieb? *g*
nix, hab mich einfach so in den Thread geschmuggelt *g*
Post by Michael Paap
Wir philosophieren hier ja nicht im luftleeren Raum über Seiteneffekte,
zumindest hatte ich nicht die Absicht. ;-)
och... wir sind doch dclj, oder?

Grsuss theo
Michael Paap
2008-10-16 07:02:44 UTC
Permalink
Post by Jochen Theodorou
Post by Michael Paap
Ich kann akzeptieren, dass du das Ändern eines Attributes nicht als
Seiteneffekt siehst. Es hat dann halt nur absolut garnichts mit
meinem Begriff für Seiteneffekt zu tun.
Den Eindruck habe ich auch, ja. Ist ja auch nicht schlimm, aber was
bitte hat dein Begriff von Seiteneffekt mit dem zu tun, was Heiner
Kücker als Antwort auf Mike Wesling schrieb? *g*
nix,
*Ächz*.
Post by Jochen Theodorou
hab mich einfach so in den Thread geschmuggelt *g*
Ok, dann sind wir uns anscheinend ziemlich einig, außer bezüglich der
Frage, ob derlei Schmuggelei zur Klarheit beiträgt. Ich mag es ja, wenn
sich Postings, die sich als Antwort auf ein anderes Posting ausgeben,
halbwegs darum bemühen, das Thema beizubehalten. *g*

Bist du Rheinländer? Die machen das hier dauernd so... die warten auf
irgend ein Stichwort, um einen dann zu unterbrechen, mit einem "Wo du
jrad Hölzchen sachst, ich hab da neulich..." und dann fangen sie an,
über Forstwirtschaft zu referieren. Wobei der Zusammenhang des
Stichworts zu dem, was sie loswerden wollen, ausschließlich von der Zeit
abhängt, die sie gewartet haben. Irgendwann passt alles "irjendswie". ;-)
Post by Jochen Theodorou
Post by Michael Paap
Wir philosophieren hier ja nicht im luftleeren Raum über Seiteneffekte,
zumindest hatte ich nicht die Absicht. ;-)
och... wir sind doch dclj, oder?
Ja, schon. Aber das rechtfertigt doch nicht alles! :-)

Gruß,
Michael
Jochen Theodorou
2008-10-16 11:03:52 UTC
Permalink
Michael Paap schrieb:
[...]
Post by Michael Paap
Post by Jochen Theodorou
hab mich einfach so in den Thread geschmuggelt *g*
Ok, dann sind wir uns anscheinend ziemlich einig, außer bezüglich der
Frage, ob derlei Schmuggelei zur Klarheit beiträgt. Ich mag es ja, wenn
sich Postings, die sich als Antwort auf ein anderes Posting ausgeben,
halbwegs darum bemühen, das Thema beizubehalten. *g*
ich habe mich nicht auf den OP bezogen, aber auf die Diskussion zwischen
dir und Heiner, die mit dem OP eh schon nichts mehr zu tun hat.
Ansonsten wäre ich natürlich beim Thema geblieben
Post by Michael Paap
Bist du Rheinländer? Die machen das hier dauernd so... die warten auf
irgend ein Stichwort, um einen dann zu unterbrechen, mit einem "Wo du
jrad Hölzchen sachst, ich hab da neulich..." und dann fangen sie an,
über Forstwirtschaft zu referieren. Wobei der Zusammenhang des
Stichworts zu dem, was sie loswerden wollen, ausschließlich von der Zeit
abhängt, die sie gewartet haben. Irgendwann passt alles "irjendswie". ;-)
lol... ich glaube ich kenne wirklich zu wenig Rheinländer. Um deine
Frage zu beantworten... bin kein Rheinländer.

Gruss theo
Lesen Sie weiter auf narkive:
Suchergebnisse für 'Design-Frage' (Newsgroups und Mailinglisten)
10
Antworten
Designfrage Nachspezialisierung während der Verarbeitung
gestartet 2012-10-11 09:24:28 UTC
de.comp.lang.java
5
Antworten
Designfrage - RMI
gestartet 2007-03-05 15:06:43 UTC
de.comp.lang.java
6
Antworten
OT: Designfrage Währungsproblematik
gestartet 2005-12-08 08:25:17 UTC
de.comp.lang.java
13
Antworten
Designfrage ...
gestartet 2003-11-03 23:52:33 UTC
de.comp.lang.java
7
Antworten
Designfrage zu Benutzereinstellungen
gestartet 2003-12-11 10:33:19 UTC
de.comp.lang.java
Suchergebnisse für 'Design-Frage' (Fragen und Antworten)
4
Antworten
Billigeres FPGA für feste Designs?
gestartet 2014-04-20 21:40:34 UTC
elektronik
6
Antworten
Was war die Inspiration für das Design von R2-D2?
gestartet 2015-08-18 04:31:21 UTC
sci-fi
5
Antworten
Homebrew-CPUs / Low Level Design
gestartet 2011-08-31 03:58:31 UTC
elektronik
1
antworten
Kann MIDI Designer andere iPad-Apps steuern?
gestartet 2012-06-02 22:51:19 UTC
klang
3
Antworten
Wie erstellen Unternehmen für das Design integrierter Schaltkreise ihre Datenblätter?
gestartet 2015-04-29 19:54:02 UTC
elektronik
Nicht verwandte, aber interessante Themen
5
Antworten
Wie haben die Römer des 2. Jahrhunderts entschieden, wo Hadrians Mauer gebaut werden soll?
gestartet 2016-01-20 20:22:51 UTC
10
Antworten
Was ist der Ursprung des Stereotyps, dass es dem polnischen Volk an Intelligenz mangelt?
gestartet 2012-05-22 17:10:01 UTC
5
Antworten
Was ist das älteste authentische Beispiel für Menschen, die sich über die Neuzeit und die Jugend beschweren?
gestartet 2016-04-03 04:01:14 UTC
5
Antworten
Was hat Deutschland im Zweiten Weltkrieg gegen die unterschiedlichen Spurweiten in der Sowjetunion unternommen?
gestartet 2015-07-23 14:07:33 UTC
5
Antworten
Warum haben die europäischen Christen Konstantinopel nicht zurückgenommen?
gestartet 2013-09-28 08:53:33 UTC
Loading...