GridData<\/span>. Dieses hat ziemlich viele Einstellungen und wird vergleichsweise oft gebraucht. Die folge ist eine Menge Schreibarbeit und unsch\u00f6ner Code.<\/p>\nGridData listBoxData = new GridData(GridData.FILL_BOTH);\r\nlistBoxData.widthHint = 150;\r\nlistBoxData.heightHint = 150;\r\nlistBoxData.minimumWidth = 1;\r\nlistBoxData.minimumHeight = 1;\r\nlistBox.setLayoutData(listBoxData);<\/pre>\nDies ist lediglich ein Objekt. Bei geschachtelten Layouts ben\u00f6tigt man aber schnell einige davon.<\/p>\n
Oft versucht man, die m\u00f6gliche Konfiguration \u00fcber Konstruktoren<\/strong> zu erreichen. Dies ist bei einer Vielzahl an Werten, die zudem noch optional sind, oft alles andere als praktikabel. Au\u00dferdem kann man versuchen, die verschiedenen Data-Objekte in einem Baum anzuordnen und Kinder mittels Klonen<\/strong> zu erzeugen, um den Code zu verkleinern. Das macht eine so kleine Sache aber wieder zu einer Wissenschaft, die einfach nicht n\u00f6tig ist.<\/p>\nDie Factory-L\u00f6sung \u201eGridDataFactory\u201c<\/h2>\n
Eine geeignete L\u00f6sung: Eine Factory f\u00fcr die widerspenstige Klasse. F\u00fcr das GridData-Objekt sieht das ganze dann so aus:<\/p>\n
GridDataFactory.fillDefaults()\r\n\t.grab(true, true).hint(150, 150).applyTo(listBox);<\/pre>\nEine elegante L\u00f6sung, die man verallgemeinern und an vielen Stellen anwenden kann.<\/p>\n
Struktur einer Factory<\/h2>\n
F\u00fcr eine beliebige Klasse Foo<\/span>, von der wir Objekte erstellen wollen, empfiehlt sich, f\u00fcr die Factory eine eigene Klasse zu nehmen. Prinzipiell lassen sich die folgenden Methoden auch in Foo<\/span> direkt integrieren, das bl\u00e4ht die Klasse aber nur unn\u00f6tig auf. Schlie\u00dflich sind alle Methoden \u00f6ffentlich und somit der Teil der offiziellen Schnittstelle. Wir erzeugen also eine Klasse FooFactory<\/span>, welche die folgenden Methoden enth\u00e4lt:<\/p>\n\n\n\nName<\/th>\n | R\u00fcckgabetyp<\/th>\n | Beschreibung<\/th>\n<\/tr>\n |
\nstatic<\/em> defaults()<\/td>\nFooFactory<\/td>\n | Liefert ein einfachen FooFactory-Objekt.<\/td>\n<\/tr>\n | \nstatic<\/em> createFrom(Foo prototype)<\/td>\nFooFactory<\/td>\n | Liefert ein FooFactory-Objekt mit Voreinstellungen wie beim \u00fcbergebenen Foo-Objekt prototype.<\/td>\n<\/tr>\n | \nstatic<\/em> copy(FooFactory prototype)<\/td>\nFooFactory<\/td>\n | Liefert ein FooFactory-Objekt mit dem Zustand des \u00fcbergebenen FooFactory-Objekts prototype.<\/td>\n<\/tr>\n | \neigenschaft(wert)<\/td>\n | FooFactory<\/td>\n | Setzt Eigenschaft \u201eeigenschaft\u201c des FooFactory-Objekts auf \u201ewert\u201c und gibt es zur\u00fcck.<\/td>\n<\/tr>\n | \ncreate()<\/td>\n | Foo<\/td>\n | Gibt das erzeugte Foo-Objekt zur\u00fcck.<\/td>\n<\/tr>\n | \napplyTo(Bar container)<\/td>\n | void<\/td>\n | Nutzt die setFoo-Methode des Containers, um das erzeugte Foo-Objekt in container zu setzen.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n Man sieht hier sch\u00f6n, dass Methoden zum Setzen von Eigenschaften, immer das eigene Objekt zur\u00fcckgeben. Hiermit l\u00e4sst sich eine sch\u00f6ne Verkettung erreichen, wie dies im GridDataFactory-Beispiel der Fall ist. Dieses Konzept wird auch als \u201eMethod Chaining<\/strong>\u201c bezeichnet.<\/p>\nFazit: Elegant und nahezu stilkonform<\/h2>\nIch finde diesen Weg vor allem aus zwei Gr\u00fcnden sehr interessant: Zun\u00e4chst die offensichtliche Leichtigkeit, mit der man auch komplexe Objekte erzeugen, duplizieren, konfigurieren und sogar in andere Objekte integrieren kann<\/strong>.<\/p>\nDer andere wichtige Punkt ist, dass man bestehende Coding-Guidelines nicht direkt verletzt<\/strong>. Die obige Beispielklasse Foo kann sauber auf Getter und Setter setzen, wie es etwa in Java \u00fcblich ist. Anstatt nun etwa bei den Settern Method-Chaining einzubauen, was klar gegen die \u00fcblichen Konzepte versto\u00dfen w\u00fcrde, nimmt man einfach eine Factory hinzu. Diese ist zwar auch nicht mit den \u00fcblichen Konventionen vereinbar, aber das ist an dieser Stelle akzeptabel: Einerseits wurde sie direkt geschaffen, um bestehende Konventionen zu umgehen<\/strong>. Dies muss auch entsprechend dokumentiert und dem Nutzer klar gemacht werden.<\/strong> Andererseits ist das gesamte Projekt auch ohne die Factory nutzbar. Wer sich auf den \u201eKonventionsbruch\u201c nicht einlassen m\u00f6chte, erzeugt seine Objekte einfach weiterhin auf dem klassischen Weg.<\/p>\n\nBeispielquellen<\/h2>\nDie SWT-Beispiele zur GridDataFactory sind aus der Eclipse-Dokumentation<\/a>.<\/section>\n","protected":false},"excerpt":{"rendered":"Heute m\u00f6chte ich einmal eine andere M\u00f6glichkeit aufzeigen, wie man Factorys sinnvoll nutzen kann: Um schnell und mit geringem Code-Aufwand komplexe Objekte zu erzeugen und zu konfigurieren. Ich hoffe, dass ich keinem Anh\u00e4nger der \u201eGang of Four\u201c auf die F\u00fc\u00dfe trete, hat dieser Ansatz doch vergleichsweise wenig mit der \u201eFactory Method\u201c oder \u201eAbstract Factory\u201c zu tun.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[91],"tags":[],"_links":{"self":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/321"}],"collection":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/comments?post=321"}],"version-history":[{"count":18,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/321\/revisions"}],"predecessor-version":[{"id":1812,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/321\/revisions\/1812"}],"wp:attachment":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/media?parent=321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/categories?post=321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/tags?post=321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}} | | | |