FB18 - Das Forum für Informatik

fb18.de / Diplom Informatik / Praktische Informatik (HS)

Entwurfsmuster?

Entwurfsmuster? 2006-08-28 15:37
Anonymer User
moin moin,

ich raffe nicht, was Entwurfsmuster bedeutet.
Muster ist eine Abstraktion von einer konkretren Form, oder ein Beispiel einer Form, in die man sich orientieren kann. aber was ist Entwurfsmuster? ein Muster, das in der Entwurfsphase eingesetzt wird.
Hat jemand eine andere Formulierung? + Beispiele

DANKE!!!

(edit fal: Topictitel)

Re: Entwurfsmuster? 2006-08-28 15:38
Marrow
http://de.wikipedia.org/wiki/Entwurfsmuster

Den Artikel hast du schon gelesen?
Ich finde ihn eigentlich sehr gut verständlich.

Re: Entwurfsmuster? 2006-08-28 15:45
Pocmo
Grob gesagt würde ich es so beschreiben: Entwurfsmuster (Design Patterns) sind einfache Vorlagen für kleine Teilprobleme, die sich bewährt haben.

Und noch ein Beispiel, ein Singleton:

public class MyClass { public synchronized getInstance() { if(instance == null) { instance = new MyClass(); } return instance; } private static MyClass instance; }

Das Singleton-Muster ist also brauchbar, wenn von einer Klasse immer nur ein Objekt existieren soll.

Re: Entwurfsmuster? 2006-08-28 15:57
Anonymer User
Singleton … bewährt …. *hust*

Ansonsten: Die Zusammenfassung am Anfang der Wikipedia-Seite trifft es schon gut.

LEIFer

Re: Entwurfsmuster? 2006-08-28 19:08
Fred
Du hast vergessen, einen privaten Konstruktor zu definieren.

Re: Entwurfsmuster? 2006-08-29 00:59
FireTiger
Du hast vergessen, einen privaten Konstruktor zu definieren.
Kleinkram. [img]http://www.fb18.de/gfx/24.gif[/img]

Re: Entwurfsmuster? 2006-08-29 10:31
Anonymer User
Und diese Pseudo-Späte-Initialisierung ist in Java in 99,9% der Anwendungen eher hinderlich. Meist ist die schlicht direkte Initialisierung der Klassenvariable besser:
public class MyClass { private MyClass() { // Empty on purpose, we just need a private constructor } public getInstance() { return instance; } private static MyClass instance = new MyClass(); }LEIFer

Re: Entwurfsmuster? 2006-08-29 14:08
FireTiger
Und diese Pseudo-Späte-Initialisierung ist in Java in 99,9% der Anwendungen eher hinderlich. Meist ist die schlicht direkte Initialisierung der Klassenvariable besser.

LEIFer

Wieso Pseudo? Und wieso ist das eher schlecht?

Re: Entwurfsmuster? 2006-08-29 14:24
Anonymer User
schlecht ist daran z.B., dass die Zeit davor (z.B. direkt nach dem Programmstart) ungenutzt ver-wartet wird,
und dann beim ersten Einsatz muss man warten, bis das Objekt initialisiert wird,

ist aber bei LEIFs Ansatz normalerweise genauso,
vielleicht meite er was anderes ;)

schlecht ist auf jeden Fall die Operation synchronized zu machen,
x-mal dieser Aufwand der Synchronisierung, der doch nur einmal am Anfang wichtig wäre

Re: Entwurfsmuster? 2006-08-29 15:41
Anonymer User
Die Klassenvariablen werden beim Laden einer Klasse gesetzt. JVMs laden ihre Klassen fast immer erst dann, wenn das erste Mal eine Operation an ihnen aufgerufen oder auf ein Feld bei Ihnen zugegriffen wird. Bei einem Singleton bedeutet dies, dass die Klasse meist erst dann geladen - und damit auch erst ein Exemplar erzeigt - wird, wenn man getInstance() daran aufruft. D.h. wenn man die Initialisierung in getInstance() macht, ist sie nur minimal später, als wenn man sie direkt in der Intialisierung der Klassenvariable macht. Deswegen meine ich, dass dies nur eine scheinbar verzögerte Initialisierung ist: Sie ist praktisch nicht verzögert.

Richtiggehend "schlecht" ist eine Initialisierung in getInstance() zwar auch nicht, aber sie benötigt eine Synchronisation und eine if-Anweisung in jedem Zugriff. Die Synchronisation ist in heutigen JVMs auch nicht mehr so schmerzhaft, wie sie es mal beim jdk 1.0 war, aber sie ist eben dennoch da und könnte sich ggf. mit einer anderen Synchronisation an der selben Klasse beißen. Die If-Anweisung kostet ebenfalls nicht die Welt, aber man kann den Sourcecode eben auch einfacher gestalten, ohne dass es einem weh tut.

Oder? Tut einem die Initialisierung direkt an der Definition der Klassenvariable wirklich nicht weh? Doch, es gibt da Szenarien: Zum einen ist das verzögerte Laden der Klassen in JVMs zwar heute absoluter Standard, aber verlassen kann man sich darauf nicht. Zum anderen gibt es eben doch den Fall (insbesondere bei kreisförmigen) Abhängigkeiten, dass eine Initialisierung nicht schon beim Laden der Klasse geschehen darf.

Der zweite Fall begegnet mir äußerst selten. Den ersten Fall sehe ich etwas kritischer, denn man sollte mit solchen Annahmen vorsichtig sein. Allerdings muß man betrachten, welche Folgen es hat, wenn die Annahme der verzögerten Initialisierung durch verzögertes Klassenladen nicht mehr zutrifft: In den allermeisten Fällen bedeutet dies nur, dass ein paar wenige Objekte früher als nötig erzeugt werden. Sehr selten erlebe ich es, dass die Singleton-Objekte knappe Resourcen in so großem Ausmaß belegen, dass dies ein frühe Initialisierung des Objektes zu einem Desaster werden ließe.

Deswegen mache ich eine später Initialisierung in getInstance() wirklich nur in den seltenen Fällen, wenn die Initialisierung sehr teuer ist oder sie beim Laden der Klasse Probleme macht. (OK, genaugenommen vermeide ich heutzutage Singeltons sowieso an vielen Stellen, da sie oft unnötig sind und einem bei Tests öfter mal im Weg sind, wenn man das Singleton durch ein Testobjekt ersetzen will.)

Ach, ja, zu dem Anonymen: Syncronized ist nötig, wenn man zusichern will, dass wirklich nur ein Exemplar des Singletons erzeugt wird. Sonst könnten zwei Threads gleichzeitig "getInstance()" aufrufen und in instance null vorfinden.

Und falls es jemand noch nicht gehört hat: Double checked locking ist auch keine clevere Lösung, sondern böse.

LEIFer

Re: Entwurfsmuster? 2006-08-30 12:08
Anonymer User
Ein mögliches Zwischending?

public class MyClass {

private static ThreadLocal<MyClass> threadLocal = new ThreadLocal<MyClass>();

private MyClass(){
}

public MyClass getInstance(){
if(threadLocal.get() == null)
threadLocal.set(new MyClass());
return threadLocal.get();
}

}

Re: Entwurfsmuster? 2006-08-30 12:32
Anonymer User
Wieso sollte man mit einem ThreadLocal auf das syncronized verzichten können? Wie zuvor kann es so passieren, dass mehrere Exemplare der Klasse erzeugt werden, wobei alle bis auf eine dann wieder verworfen werden.

Man soll mit ThreadLocal wohl Double checked locking reparieren können, wobei ich mir das nie näher angesehen habe. Ich konnte immer eine einfachere Lösung verwenden und hatte nie die Notwendigkeit für eine "toll ausgeklügelte". KISS

LEIFer

Re: Entwurfsmuster? 2006-08-30 14:16
Slater
> schlecht ist auf jeden Fall die Operation synchronized zu machen
war von mir (das zweite anyonmye aber nicht)

interessant, dass das Double-checking nicht geht,

ich vermisse bei den Lösungsvorschlägen die Variante
class Foo { private Helper helper = null; private boolean init = false; public Helper getHelper() { if (init == false) { synchronized(this) { if (init == false) { helper = new Helper(); init = true; } } } return helper; } } geht die auch nicht?
notfalls beim ersten Setzen die Zeit merken und nach 10 Min. mit dem synchronized aufhören ;)

ist zwar bisschen aufwendiger, aber allemal besser als die ganze Operation synchronized zu machen, das ist ja Wahnsinn ;)

gleich initialisieren oder wenns nicht am Anfang geht dann später mit createInstance() ist natürlich schicker, klar

Re: Entwurfsmuster? 2006-08-30 15:18
Anonymer User
geht die auch nicht?
Ernsthaft: Ich weiß es nicht. In WardsWiki wird (etwa mittig auf der Seite) behauptet, dass eine boolean-Hilfsvariable einem auch nicht hilft, da der Compiler die Anweisungen dennoch so umsortieren darf, dass es zu Problemen führt.

Ich weiß aber nicht ob das stimmt, da ich mich nie intensiv mit dem aktuellen Java Memory Model (der JLS, 3rd Edition) auseinandergesetzt habe. Ich sollte irgendwann mal "Java Concurrency in Practice" lesen. (Hat das hier jemand gelesen?)

ist zwar bisschen aufwendiger, aber allemal besser als die ganze Operation synchronized zu machen, das ist ja Wahnsinn ;)
Nein, das ist kein Wahnsinn. Es ist eher ein Wahnsinn, wenn man Optimierungen schreibt, deren Auswirkungen man nicht richtig beurteilen kann.

So teuer ist synchronized auch nicht mehr.

Wenn ich eines aus Doug Leas "Concurrent Programming in Java" gelernt habe, dann das ich zu wenig von den möglichen Fallstricken bei dem parallelen Zugriff auf gemeinsame Variablen verstehe, als dass ich hierbei fehlerlos eigene Optimierungen schreiben könnte. Ergo: Ich benutze Muster oder Bibliotheken, von denen keine (groben Schnitzer) bekannt sind. Ich benutze bei Parallelität keine "das müßte doch eigentlich viel besser sein" Annahmen.

LEIFer

Re: Entwurfsmuster? 2006-08-30 17:06
Anonymer User
Ein mögliches Zwischending?
public class MyClass { private static ThreadLocal<MyClass> threadLocal = new ThreadLocal<MyClass>(); private MyClass(){ } public MyClass getInstance(){ if(threadLocal.get() == null) threadLocal.set(new MyClass()); return threadLocal.get(); } }
OK, ich habe mir das gerade mal richtig angeguckt: Dieser Code ist ja absoluter Quatsch. Zumindest wenn man meint, damit ein Singleton zu implementieren, denn durch das ThreadLocal erhält jeder Thread ein eigenes Exemplar. Bei einem Singleton will man aber ja für alle Threads das selbe Exemplar benutzen.

Wie man, wenn man denn wirklich will, mit ThreadLocal DCL korrekt reparieren kann, stand in den Links, die ich zuvor gepostet hatte.

LEIFer

Re: Entwurfsmuster? 2007-01-08 14:01
Fred
Singleton … bewährt …. *hust*
*hatschi*

Re: Entwurfsmuster? 2007-01-08 16:13
Anarch
Uuaaahhhhh… *schüttel*