<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4981594068570960202</id><updated>2011-08-09T16:40:18.244+02:00</updated><category term='ByteCodeDeluxe'/><category term='Netbeans'/><category term='Design'/><category term='IntelliJ IDEA'/><category term='Java'/><category term='Drei Plugins'/><category term='Privat'/><category term='DSL'/><category term='Eclipse'/><title type='text'>IDEDeluxe</title><subtitle type='html'>Luxus für den Softwareentwickler! (oder: Wie mache ich mir selbst das Leben leichter?)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-8694325513073902273</id><published>2010-11-17T07:23:00.000+01:00</published><updated>2010-11-17T07:23:43.471+01:00</updated><title type='text'>Codeo</title><content type='html'>Die Lage beginnt sich zu normalisieren. Aber da abzusehen ist das mir für private Programmierprojekte in absehbarer Zukunft keine Zeit bleibt wird sich dieser Blog ein wenig verändern. Er wird wohl alles wiederspiegeln was mich auf der Arbeit beschäftigt.&lt;br /&gt;&lt;br /&gt;Bis vor etwa einem Jahr war ich leitender Entwickler für die ActionScript-IDE &lt;a href="http://fdt.powerflasher.de/"&gt;FDT&lt;/a&gt;. Im Programmieralltag stand das Parsen des Sourcecodes und das Aufbauen von Funktionalitäten auf dem resultierenden AST/Model im Vordergrund. Hier hatte ich viel Spaß.&lt;br /&gt;&lt;br /&gt;Nun habe ich Wohnort und Arbeitsplatz gewechselt und arbeite wieder an einem großen Eclipseprojekt. Diesmal handelt es sich um &lt;a href="http://wwwmaster.sysgo.com/products/pikeos-rtos-and-virtualization/eclipse-based-codeo/"&gt;CODEO&lt;/a&gt;, eine IDE auf Eclipsebasis zum Entwickeln von Software für eingebette Systeme. Ich bin gespannt welche Erfahrungen von FDT ich hier einbringen können werde, wo Überschneidungen zu sehen sind und wo sie sich grundlegend Unterscheiden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-8694325513073902273?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/8694325513073902273/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2010/11/codeo.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/8694325513073902273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/8694325513073902273'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2010/11/codeo.html' title='Codeo'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-1156602951743659686</id><published>2010-06-12T09:03:00.001+02:00</published><updated>2010-06-12T09:06:37.827+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Privat'/><title type='text'>Private Projekte</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_dg_hQZkpuBU/TBMw9JqjdyI/AAAAAAAAAB4/Jk1yx3cw3-I/s1600/GuckKlein.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dg_hQZkpuBU/TBMw9JqjdyI/AAAAAAAAAB4/Jk1yx3cw3-I/s320/GuckKlein.JPG" /&gt;&lt;/a&gt;ByteCodeDeluxe ist leider erst mal auf Eis gelegt. Sehr schade, habe viel Spaß damit gehabt. Doch momentan habe ich zwei Projekte die alle Freizeit voll in Anspruch nehmen. Mal schaun wies in einigen Monaten aussieht ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-1156602951743659686?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/1156602951743659686/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2010/06/projekte.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/1156602951743659686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/1156602951743659686'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2010/06/projekte.html' title='Private Projekte'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_dg_hQZkpuBU/TBMw9JqjdyI/AAAAAAAAAB4/Jk1yx3cw3-I/s72-c/GuckKlein.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-3052089477470002433</id><published>2010-01-05T06:58:00.000+01:00</published><updated>2010-01-05T06:58:48.502+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Drei Plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='ByteCodeDeluxe'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>Drei Plugins - Annotation Processor</title><content type='html'>Ein schönes neues Jahr! Es ist die Zeit wieder an die Arbeit zu gehen ... und die Zeit für ein kleines Update über den Entwicklungsstand der drei Plugins.&lt;br /&gt;&lt;br /&gt;Die Entwicklung des Parsers unter Nutzung der Reflection API ist relativ weit gut gegangen. Leider bin ich an eine Stelle gekommen an der ich keine andere Möglichkeit sah als die Struktur des Bytecodes doch noch ein zweites mal zu codifizieren ... und genau das wollte ich ja vermeiden. Der Wunsch nach Codegenerierung aus den Annotations wurde laut. Und genau das leisten Java Annotation Processors.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Ein Annotation Processor wird in den Compiliervorgang eingeklinkt und erweitert quasi den Compiler. Er kann Errors, Warnings und Code generieren. Das kann sowohl Sourcecode sein, der dann in einer weiteren Runde kompiliert wird, oder direkt Bytecode. Alle drei IDEs unterstützen Annotation Processoren, so dass die Portierbarkeit des Codes nicht eingeschränkt wird.&lt;br /&gt;&lt;br /&gt;Natürlich wird die Umstellung die Entwicklungszeit verlängern. Lohnt sich dieser Aufwand? Da der Lernprozess für mich an dieser Arbeit mindestens ebenso wichtig ist wie das Ergebnis ist die Antwort "Ja". Hier folge ich dem Motto: "Sei Konservativ auf der Arbeit und tue was du bereits kannst, in der Freizeit ist Platz für Experimente!".&lt;br /&gt;&lt;br /&gt;Ein Problem welches sich mir bei der Arbeit mit Annotation Processoren stellt ist die Testbarkeit derselben. End-To-End-Tests sind leicht zu realisieren, allerdings dauert der programmatische Aufruf des Compilers auf meinem, relativ aktuellen, System bereits eine halbe Sekunde. Das schränkt die Nutzbarkeit als TDD-Tests ein wenig ein. Und die API zu mocken ist relativ schwierig (kurze Diskussion: &lt;a href="http://stackoverflow.com/questions/1811967/how-to-write-automated-unit-tests-for-java-annotation-processor"&gt;http://stackoverflow.com/questions/1811967/how-to-write-automated-unit-tests-for-java-annotation-processor&lt;/a&gt;). Sobald ich Sicherheit gewonnen habe wie ich hier vorgehe werde ich darüber berichten. Für einen kurzen Eindruck ... so sieht momentan mein Code aus für einen End-To-End-Test, der verifiziert das ein Error-Marker an einer bestimmten Stelle im Code erzeugt wurde.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #666666;"&gt;@Test&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: purple;"&gt;public void&lt;/span&gt;&lt;/b&gt; missingStructureAnnotationOnMainClass() &lt;b&gt;&lt;span style="color: purple;"&gt;throws&lt;/span&gt;&lt;/b&gt; Exception {&lt;br /&gt;    SourceBuilder file = &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; SourceBuilder();&lt;br /&gt;    file.line(&lt;span style="color: blue;"&gt;"import com.idedeluxe.binary.*;"&lt;/span&gt;);&lt;br /&gt;    file.line(&lt;span style="color: blue;"&gt;"@Binary ???class Foo {}"&lt;/span&gt;);&lt;br /&gt;    &lt;i&gt;assertMarkersAreGenerated&lt;/i&gt;(file);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Hier wird sicher gestellt, dass ein Error Marker für die Klasse "Foo" erstellt wird. Intern wird dafür die Eingabe Analysiert, die Position(en) von "???" gespeichert und aus der Eingabe entfernt, der Compiler wird zusammen mit dem Annotation Processor auf die Eingabe angesetzt und es wird verifiziert, dass die Marker an der angegeben Stellen erzeugt werden (und keine Überflüssigen Marker erzeugt werden).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-3052089477470002433?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/3052089477470002433/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2010/01/drei-plugins-annotation-processor.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/3052089477470002433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/3052089477470002433'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2010/01/drei-plugins-annotation-processor.html' title='Drei Plugins - Annotation Processor'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-3230304988092116100</id><published>2009-11-21T09:17:00.001+01:00</published><updated>2009-11-21T09:18:54.411+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Rewrite or Refactor?</title><content type='html'>Das Team arbeitet seid einigen Jahren an dem Produkt. Es ist erfolgreich und verdient gutes Geld. Die Kunden sind glücklich (auch wenn sie sich beschweren, im großen und ganzen sind sie glücklich). Aber hinter den Kulissen brodelt es. Die Entwickler haben keinen Spaß mehr an der Arbeit. Jedes neue Feature braucht länger als das vorhergehende. Das Management muss immer wieder katastrophal hohe Zeitschätzungen entgegennehmen die sich mit keinem Marketingplan vertragen. Die Entwickler werden gedrängt zu sparen und "schneller zu entwickeln, wir haben keine Wahl!". Und irgendwann ist es so weit: die Entwickler nehmen all ihren Mut zusammen und sprechen mit dem Chef.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Entwickler:&lt;/b&gt; "Wir können so nicht mehr arbeiten. Das alte System ist verrottet. Natürlich können wir weiter Features einbauen, aber wegen dem schlechten Code wird das immer langsamer werden. Und langsamer. Und langsamer. Das wird richtig teuer und immer teurer! Wir haben nur eine Möglichkeit ... wir müssen das System neu schreiben!".&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Chef:&lt;/b&gt; "Aber wird das neu schreiben nicht auch teuer? Wird es nicht sehr lange dauern?"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entwickler:&lt;/b&gt; "Natürlich wird es einige Zeit beanspruchen. Aber wir sind auch in einer sehr starken Position. Wir haben all das schon mal gemacht. Wir wissen jetzt genau was das System können muss und können von Anfang an die Anforderungen haargenau definieren. Wir werden viel schneller sein als beim ersten mal denn wir können die Architektur diesmal genau an die Anforderungen anpassen. Wir setzen uns hin, analysieren den alten Code und schreiben die Anforderungsliste haarklein nieder. Dann entwickeln wir die passende Architektur. Und zum Schluss brauchen wir bloß noch alles runter zuschreiben."&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Chef:&lt;/b&gt; "Na gut, wie lange schätzt ihr denn dass ihr brauchen werdet?"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entwickler:&lt;/b&gt; "Eine exakte Schätzung ist zwar sehr schwierig, aber wir haben uns natürlich schon Gedanken gemacht. Wir denken, dass wir das in drei bis sechs Monaten geschafft haben. Das mag zwar viel klingen, aber die Zeit haben wir schnell wieder raus. Schließlich arbeiten wir dann auf einer sauberen Architektur und können neue Features viel schneller entwickeln."&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Nach einigem hin und her sind sich alle einig. Die beste Lösung ist es tatsächlich das System neu zu schreiben und dann auf dem neuen, sauberen, komplett getestetem Code effizient neue Features zu implementieren.&lt;br /&gt;&lt;br /&gt;Wird das Erfolg haben?&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Konsequenzen&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Die Welt steht nicht still. Die Annahme, dass man alle Anforderungen durch eine Analyse der vorhandenen Anwendung gewinnen kann ist naiv. Die Software wird von Kunden verwendet, in einer sich schnell ändernden Welt. Das Management kommt nicht ohne Grund häufig zu den Entwicklern und verlangt "dieses Feature so schnell wie möglich". Den letzten beißen die Hunde und die Konkurrenz schläft nicht. Ein Feature das heute das Geld in die Taschen spült ist in drei Monaten keinen Pfifferling mehr wert. Wenn ein halbes Jahr eingeplant wird um Funktionalität neu zu implementieren die schon vorhanden ist (wenn auch häßlich, schlecht wartbar, nicht erweiterbar ...) dann kommen zwangsläufig während dieser Zeit neue Anforderungen. Und diese können nicht einfach ignoriert werden. Die Kunden erwarten Fortschritt, die Software muss verkauft werden weil jede nicht verkaufte Lizenz bares Geld kostet.&lt;br /&gt;&lt;br /&gt;Weil sich die Anforderungen also auch während der Neuentwicklung ändern gibt es zu Anfang der Neuentwicklung keine Chance eine vollständige Anforderungsliste zu erstellen. Genauso wie immer werden sich die Anforderungen während der Entwicklung ändern. Und die Architektur wird unvollkommen sein. Während der Neuentwicklung werden unvorhergesehene Anpassungen vornehmen müssen, was den Gesamtaufwand vergrößert. Die Entwicklung wird länger dauern als geplant war, es werden noch mehr neue Anforderungen kommen und der Druck wird steigen.&lt;br /&gt;&lt;br /&gt;Der Druck wird so weit steigen, dass das Management die Entwickler bittet das neue Feature "so schnell wie irgend möglich" einzubauen. Wieder werden Kompromisse gemacht werden. Das Ende vom Lied ist, dass die Anwendung trotz allem guten Willens nach einigen Jahren genauso verrottet ist wie die Alte. Und der Wunsch alles neu zu machen, alles "auf saubere Füße zu stellen", kommt auf. Es ist nichts gewonnen, nur eine Menge Zeit verloren.&lt;br /&gt;&lt;br /&gt;Aber was ist die Alternative?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Ursachen&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Um die Alternative zu finden muss zuerst das eigentliche Problem erkannt werden. Der alte, verrottete, nicht erweiterbare Code ist &lt;b&gt;nicht&lt;/b&gt; schuld. Code kann keine Schuld tragen, es ist nur ein Text. Und dieser ist nur ein Ding, nichts dem man eine Schuld für irgend etwas geben könnte.&lt;br /&gt;&lt;br /&gt;Das Management ist auch &lt;b&gt;nicht&lt;/b&gt; Schuld. Die Prioritäten des Managements müssen "so viele Features so schnell wie möglich" sein, denn das ist es was die Kunden wollen. Und man kann nicht erwarten das jede Person in der Hierarchie die Probleme der Entwickler versteht, das verstanden wird was es bedeutet wenn der Code verrottet und welche Entscheidungen dazu führen, dass dies geschieht.&lt;br /&gt;&lt;br /&gt;Die letztliche Verantwortung über die Qualität der Software kann nur bei den Entwicklern liegen. Nur hier sind alle Informationen und alles Wissen (hoffentlich) verfügbar um die täglichen Entscheidungen zu treffen. Um zu entscheiden: Wird dieses Feature jetzt ganz dreckig rein gehackt, oder müssen wir uns ein klein wenig Zeit nehmen? Ist ist nicht praktikabel jedes mal den Chef zu befragen ob das jetzt so oder so implementiert werden soll. So schwer das ist, diese Verantwortung kann nicht in der Hierarchie weiter nach oben gereicht werden. Die Entwickler müssen an dieser Stelle die Verantwortung akzeptieren und verantwortungsvoll handeln.&lt;br /&gt;&lt;br /&gt;Was aber heißt verantwortungsvoll? Es ist verlockend den Leuten "über einem" die Verantwortung zu geben. Auf ein "Wir brauchen dieses Feature so schnell wie möglich" mit einem "Na gut, dann scheiß ich das hier in den Code rein. Ich sag euch das wird nicht lecker, aber ihr habt es so gewollt!" zu reagieren. Der Chef wird ein Lob aussprechen, weil der Entwickler so gute Arbeit macht, die Kollegen werden ihn bewundern, weil dieses harte Feature so schnell erledigt wurde, der Entwickler wird gut dastehen.&lt;br /&gt;&lt;br /&gt;Aber er hat nicht verantwortungsvoll gehandelt. Denn die Kosten sind nicht gesunken. Sie sind gestiegen! Code wird einmal geschrieben, aber oft gelesen. Die Kosten um neue Features zu implementieren sind durch die Entscheidung ein klein wenig angestiegen, denn es ist schwieriger neue Features auf Dreck aufzubauen als auf Code der einen Unterstützt. Wenn der Code an einer oder zwei Stellen dreckig ist, weil ein Feature tatsächlich lebensnotwendig für die Firma war, dann kann man damit Leben. Wenn das Dreckige aber zur Gewohnheit wird, dann wird die Entwicklung immer langsamer und langsamer, bis es unmöglich erscheint in dem alten Kram weiter zu arbeiten.&lt;br /&gt;&lt;br /&gt;Man kann sich hier der Metapher des &lt;a href="http://martinfowler.com/bliki/TechnicalDebt.html"&gt;Schulden machens&lt;/a&gt; bedienen ... ein schnell gehacktes Feature ist wie ein Kauf auf Pump. Man kann damit glänzen, man erhält schnell ein neues Feature, und wenn man es nicht übertreibt ist es auch ok. Aber die Zinslast ist in Form gesunkener Produktivität in der Zukunft zu zahlen, und wenn die Schulden zu hoch werden muss Insolvenz angemeldet werden ... ein Rewrite steht bevor.&lt;br /&gt;&lt;br /&gt;Was also kann getan werden?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Alternative&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Jeder Entwickler muss für sich seinen Teil der Verantwortung übernehmen. Natürlich kann man immer sagen "Ich habe keine Schuld, der Entwickler vor mir hat nur Müll zurück gelassen!". Aber man muss sich, wenn man längere Zeit an einer vorhandenen Codebasis gearbeitet hat, auch fragen lassen ob es denn besser geworden ist seid man dabei ist. Hat man einfach weiter gemacht wie bisher, oder hat die eigene Arbeit zu Verbesserungen geführt? Ist die Schuldenlast gesunken?&lt;br /&gt;&lt;br /&gt;Der komplette Rewrite einer Software ist im Prinzip nichts anderes, als alle Schulden die man im Laufe der Jahre angehäuft hat mit einem Schlag zurück zu zahlen. Oder besser noch: abzuarbeiten. Aber das ist in der Regel ein zu großer Batzen, denn so lange man nur Schulden abarbeitet hat man kein Geld für den Lebensunterhalt. Daher muss eine Strategie der kleinen Schritte gefunden werden. Die Schuld muss Stück für Stück getilgt werden, damit man nebenher noch für seinen Lebensunterhalt arbeiten kann.&lt;br /&gt;&lt;br /&gt;Der erste Schritt auf diesem Weg besteht darin keine weiteren Schulden mehr aufzunehmen. Wenn die Entwickler weitermachen wie bisher, also der neue Code nicht besser ist als der Alte, dann wird sich nichts ändern. Neuer Code muss "high quality" sein! Das ist zunächst einmal ungewohnt, weil man zuerst einmal langsamer wird, aber es ist unumgänglich wenn man aus der Falle ausbrechen will.&lt;br /&gt;&lt;br /&gt;Der zweite Schritt ist es die Schulden Stück für Stück zurück zu zahlen. Der ganzen Batzen ist zu groß. Aber als Entwickler kann ich mich jedes mal, wenn ich an einer vorhandenen Codestelle arbeiten muss, fragen "Ist das guter Code? Kann ich ihn verbessern? Einfacher machen? Ist es duplizierter Code? Kann ich abstrahieren?". Und ähnliche Fragen. Dabei muss nach meiner Arbeit nicht alles Gold sein. Es muss nur ein wenig besser sein als vorher. Wenn alle Entwickler jedes mal wenn sie arbeiten dafür sorgen, dass der Code ein wenig besser wird, ein wenig der Schuld zurück gezahlt wird, ein klein wenig &lt;a href="http://www.refactoring.com/"&gt;refactoring&lt;/a&gt; betreiben, dann wird die Entwicklung langfristig wieder schneller werden. Das wird nicht innerhalb einiger Wochen geschehen, dafür ist der Code vermutlich schon zu verrottet, aber die kontinuierliche Pflege wird den Patienten wieder auf die Beine bringen.&lt;br /&gt;&lt;br /&gt;Das also ist der Weg:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Verantwortung übernehmen&lt;/li&gt;&lt;li&gt;Neuer Code muss guter Code sein&lt;/li&gt;&lt;li&gt;Den alten Code jeden Tag ein wenig verbessern&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;a href="http://blog.objectmentor.com/articles/2009/01/09/the-big-redesign-in-the-sky"&gt;Martin C. Fowler über "The big redesign in the sky"&lt;/a&gt;&lt;br /&gt;&lt;a href="http://chadfowler.com/2006/12/27/the-big-rewrite"&gt;Chad Fowler über "The big rewrite"&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-3230304988092116100?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/3230304988092116100/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2009/11/rewrite-or-refactor.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/3230304988092116100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/3230304988092116100'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2009/11/rewrite-or-refactor.html' title='Rewrite or Refactor?'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-2483500691662658525</id><published>2009-11-03T21:56:00.002+01:00</published><updated>2009-11-04T09:13:19.970+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Drei Plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='ByteCodeDeluxe'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>Drei Plugins - Model</title><content type='html'>&lt;b&gt;Modelstrukturen&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Vom Beginn an war ein Ziel in ByteCodeDeluxe, die Struktur des Bytecodes deklarativ auszudrücken. Services, wie zum Beispiel ein Bytecode Parser, arbeiten auf dieser Struktur um ihre Arbeit zu verrichten. Auf diese Weise wird vermieden, dass die Struktur des Bytecodes an verschiedenen Stellen dupliziert wird (zum Beispiel einmal für die Lese- und einmal für die Schreibroutine).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;External DSL&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Dabei wurden verschiedene Ansätze durchdacht. Eine Möglichkeit wäre eine&amp;nbsp;&lt;a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html"&gt;externe DSL&lt;/a&gt; gewesen. Die Aufgabe an sich ist schon reizvoll. Ich habe in der Vergangenheit mit ANTLR und JavaCC gearbeitet und man landet schnell bei dem Gedanken ein vergleichbares Tool für Binärdateien zu implementieren. Dies aber ist definitiv "out of scope" und würde das angestrebte Ergebnis, einen Java-ByteCodeEditor, deutlich hinauszögern. Schnell würde die Bibliothek zum Hauptaugenmerk der Implementierungsarbeit werden und Wünsche nach einem Editor und anderem Toolsupport würden laut. Deswegen wurde dieser Ansatz verworfen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;JDT - PropertyDescriptor&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Die Idee zur letztlich verwendete Implementierung stammt aus dem JDT. Eine Sourcedatei wird hier durch einen AST (im Package "org.eclipse.jdt.core.dom") beschrieben. Die Elemente diesen ASTs, zum Beispiel "MethodDeclaration", "NumberLiteral", "WhileStatement", tragen jeweils wiederum einen sogenannten "PropertyDescriptor". Diese Descriptoren beschreiben den grundsätzlichen Aufbau der Elemente. Das sieht dann im Code, hier für ein WhileStatement, so aus:&lt;br /&gt;&lt;span style="color: #0b5394;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #0b5394;"&gt;/** while( Expression ) Statement */&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: purple;"&gt;public class&lt;/span&gt;&lt;/b&gt; WhileStatement &lt;b&gt;&lt;span style="color: purple;"&gt;extends&lt;/span&gt;&lt;/b&gt; Statement {&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ChildPropertyDescriptor EXPRESSION_PROPERTY =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ChildPropertyDescriptor(WhileStatement.class, &lt;span style="color: blue;"&gt;"expression"&lt;/span&gt;,&lt;br /&gt;      Expression.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;, MANDATORY, CYCLE_RISK);&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ChildPropertyDescriptor BODY_PROPERTY =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ChildPropertyDescriptor(WhileStatement.class, &lt;span style="color: blue;"&gt;"body"&lt;/span&gt;,&lt;br /&gt;      Statement.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;, MANDATORY, CYCLE_RISK);&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;private static final&lt;/span&gt;&lt;/b&gt; List PROPERTY_DESCRIPTORS;&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;static&lt;/span&gt;&lt;/b&gt; {&lt;br /&gt;    List propertyList = &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ArrayList(3);&lt;br /&gt;    createPropertyList(WhileStatement.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;, propertyList);&lt;br /&gt;    addProperty(EXPRESSION_PROPERTY, propertyList);&lt;br /&gt;    addProperty(BODY_PROPERTY, propertyList);&lt;br /&gt;    PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Jedes Element des DOMs ist also in der Lage über seine statische Struktur Auskunft zu geben (es hat einen Namen, weiß ob es optional ist usw.). Es gibt Methoden wie "getStructuralProperty", welcher man einen Descriptor gibt und man bekommt das echte AST-Element, welches mit dieser Struktur im fraglichen Node verknüpft ist. Letztlich also eine Metabeschreibung des ASTs. Nun kann man Logik auf dieser Metabeschreibung implementieren anstatt sie direkt auf dem AST zu implementieren, die AST-Struktur leakt also nicht nach draußen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ByteCodeDeluxe 0.1 - Structure&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In ByteCodeDeluxe sind die PropertyDescriptoren ersetzt worden durch die Model-"Structure". Genau wie ein PropertyDescriptor im JDT beschreibt eine Structure einen Elementtyp des Baumes. Mit Hilfe dieser Metaebene der Beschreibung läßt sich die Struktur des Bytecodes relativ kompakt darstellen. Um zum Beispiel die Struktur einer "Method-Info" (hier der Weg zur &lt;a href="http://www.jcp.org/en/jsr/detail?id=202"&gt;Spec&lt;/a&gt;) abzubilden bedarf es folgenden Codes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #0b5394;"&gt;/** method_info {&lt;br /&gt; *   u2 access_flags;&lt;br /&gt; *   u2 name_index;&lt;br /&gt; *   u2 descriptor_index;&lt;br /&gt; *   u2 attributes_count;&lt;br /&gt; *   attribute_info attributes[attributes_count];&lt;br /&gt; *  } */&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: purple;"&gt;public class&lt;/span&gt;&lt;/b&gt; MethodInfo &lt;b&gt;&lt;span style="color: purple;"&gt;extends&lt;/span&gt;&lt;/b&gt; AbstractNode {&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; FlagStructure ACCESS_FLAGS =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; FlagStructure(&lt;span style="color: blue;"&gt;"access_flags"&lt;/span&gt;, 2, MethodFlags.values());&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ArrayIndexStructure NAME_INDEX =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ArrayIndexStructure(&lt;span style="color: blue;"&gt;"name_index"&lt;/span&gt;, 2, ClassFile.CONSTANT_POOL);&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ArrayIndexStructure DESCRIPTOR_INDEX =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ArrayIndexStructure(&lt;span style="color: blue;"&gt;"descriptor_index"&lt;/span&gt;, 2, ClassFile.CONSTANT_POOL);&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ArrayLengthStructure ATTRIBUTES_COUNT =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ArrayLengthStructure(&lt;span style="color: blue;"&gt;"attributes_count"&lt;/span&gt;, 2);&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; ArrayStructure ATTRIBUTES =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; ArrayElementCountingStructure(&lt;span style="color: blue;"&gt;"attributes"&lt;/span&gt;,&lt;br /&gt;      &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; StringSelectionStructure(&lt;span style="color: blue;"&gt;"attribute"&lt;/span&gt;, 2,&lt;br /&gt;        ClassFile.CONSTANT_POOL, AttributeInfo.ATTRIBUTES_MAP),&lt;br /&gt;      ATTRIBUTES_COUNT, &lt;b&gt;&lt;span style="color: purple;"&gt;false&lt;/span&gt;&lt;/b&gt;);&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public static final&lt;/span&gt;&lt;/b&gt; Structure[] STRUCTURE =&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;new&lt;/span&gt;&lt;/b&gt; Structure[] { ACCESS_FLAGS, NAME_INDEX, DESCRIPTOR_INDEX,&lt;br /&gt;      ATTRIBUTES_COUNT, ATTRIBUTES };&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public&lt;/span&gt;&lt;/b&gt; Structure[] getStructure() {&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;return&lt;/span&gt;&lt;/b&gt; STRUCTURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: purple;"&gt;public&lt;/span&gt;&lt;/b&gt; String getName() {&lt;br /&gt;    &lt;b&gt;&lt;span style="color: purple;"&gt;return&lt;/span&gt;&lt;/b&gt; ((ArrayIndex) getChild(NAME_INDEX)).getTarget().&lt;br /&gt;      getValueString();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mit diesem Werkzeugkoffer ist die Spec relativ schnell runter geschrieben. Ein Parser traversiert dann nur noch die (statische) Struktur und instantiiert Nodes die dann als Model dienen und die Daten speichern. Dadurch haben die Nodes allerdings eine Doppelfunktion ... einerseits sind sie die Strukturbeschreibung des Bytecodes, andererseits dienen sie als Modelelemente und halten die eingelesenen Daten. Durch diese Doppelfunktion neigen sie dazu Funktionalität anzuziehen und damit zu Hybriden zu werden (nicht ganz Klasse nicht ganz Datenstruktur ... an dieser Stelle möchte ich einmal einen Hinweis auf das wundervolle Buch &lt;a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew"&gt;"Clean Code"&lt;/a&gt; geben). Auch wird man den Gedanken nicht los, ob es nicht doch noch ein wenig kompakter geht.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ByteCodeDeluxe&lt;/b&gt;&lt;b&gt; 0.2 - Structure&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In der Version 0.2 sollen die großen zwei Schwächen der alten Struktur, Doppelfunktion der Strukturnodes und suboptimale Lesbarkeit der Bytecodebeschreibung, ausgemerzt werden. Die Beschreibung soll nicht mehr als Datencontainer dienen und deutlich verkürzt werden.&lt;br /&gt;&lt;br /&gt;Die Idee ist, die Struktur mit Hilfe von Java-Klassen zu beschreiben und reflektiv auszulesen, also den Javasource quasi direkt als deklarative Beschreibungssprache zu nutzen. Annotations können verwendet werden um das Modell mit zusätzlichen Informationen anzureichern. Services können dann auf dieser Struktur arbeiten.&lt;br /&gt;&lt;br /&gt;Dieses Vorgehen bringt offensichtlich einen Performanceoverhead mit sich. Aber: auch der alte Ansatz ist mit Sicherheit nicht besonders performant, für die Modelle werden sehr viele Objekte instantiiert. Außerdem ist die Performance in diesem Kontext von untergeordneter Bedeutung. Für den Editor werden immer nur einige wenige class-Dateien geöffnet und wenn das eine hundertstel Sekunde (oder auch eine zehntel Sekunde) dauert ist das nicht weiter schlimm.&lt;br /&gt;&lt;br /&gt;Wie könnte eine solche Annotation nun konkret aussehen? Ich bin noch dabei an den Details zu arbeiten, aber ich stelle mir in etwa folgendes vor:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: #0b5394;"&gt;/** method_info {&lt;br /&gt; *   u2 access_flags;&lt;br /&gt; *   u2 name_index;&lt;br /&gt; *   u2 descriptor_index;&lt;br /&gt; *   u2 attributes_count;&lt;br /&gt; *   attribute_info attributes[attributes_count];&lt;br /&gt; *  } */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;@Structure&lt;/span&gt;( { &lt;span style="color: blue;"&gt;"accessFlags"&lt;/span&gt;, &lt;span style="color: blue;"&gt;"nameIndex"&lt;/span&gt;, &lt;span style="color: blue;"&gt;"descriptorIndex"&lt;/span&gt;,&lt;br /&gt;              &lt;span style="color: blue;"&gt;"attributesCount"&lt;/span&gt;, &lt;span style="color: blue;"&gt;"attributes"&lt;/span&gt; })&lt;br /&gt;&lt;b&gt;&lt;span style="color: purple;"&gt;public class&lt;/span&gt;&lt;/b&gt; MethodInfo {&lt;br /&gt;  &lt;span style="color: #666666;"&gt;@Flags&lt;/span&gt;(MethodAccessFlags.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;  U2 accessFlags;&lt;br /&gt;  &lt;span style="color: #666666;"&gt;@ConstantPoolIndex&lt;/span&gt;(ConstantUtf8Info.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;  U2 nameIndex;&lt;br /&gt;  &lt;span style="color: #666666;"&gt;@ConstantPoolIndex&lt;/span&gt;(ConstantUtf8Info.&lt;b&gt;&lt;span style="color: purple;"&gt;class&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;  U2 descriptorIndex;&lt;br /&gt;  &lt;span style="color: #666666;"&gt;@TableSize&lt;/span&gt;(tableName = &lt;span style="color: blue;"&gt;"attributes"&lt;/span&gt;)&lt;br /&gt;  U2 attributesCount;&lt;br /&gt;  AttributeInfo[] attributes;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Die Informationsmenge ist in etwa so hoch wie im Beispiel von Version 0.1, allerdings deutlich kompakter geschrieben. Ein Parser würde nun reflektiv die Klassenstruktur mit den Annotations lesen und benutzen um den Input zu parsen und die Modelelemente zu instantiieren.&lt;br /&gt;&lt;br /&gt;Mit Hilfe dieser Struktur ist der Code nun beinahe so kompakt als wäre es eine DSL. Nur muss weder ein Parser geschrieben werden, noch ein eigenes Toolset entwickelt werden ... die Java-Reflection-API und jede beliebige Java-IDE reicht als Toolset und die Beschreibung des Bytecodes ist rein deklarativ!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-2483500691662658525?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/2483500691662658525/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2009/11/drei-plugins-model.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/2483500691662658525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/2483500691662658525'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2009/11/drei-plugins-model.html' title='Drei Plugins - Model'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4981594068570960202.post-8223590124348767592</id><published>2009-10-22T20:01:00.005+02:00</published><updated>2009-11-04T09:13:08.724+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IntelliJ IDEA'/><category scheme='http://www.blogger.com/atom/ns#' term='Drei Plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='ByteCodeDeluxe'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Drei Plugins - Eröffnung</title><content type='html'>&lt;span style="font-size: small;"&gt;&lt;b&gt;Präludium&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_dg_hQZkpuBU/StyJ8oznctI/AAAAAAAAABg/WrxSLkInonc/s1600-h/ides.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dg_hQZkpuBU/StyJ8oznctI/AAAAAAAAABg/WrxSLkInonc/s320/ides.png" /&gt;&lt;/a&gt;Vor kurzem wurde bekannt gegeben, dass der &lt;a href="http://blogs.jetbrains.com/idea/2009/10/intellij-idea-open-sourced/"&gt;Source Code von IntelliJ IDEA&lt;/a&gt; veröffentlicht wird. Mich&amp;nbsp;persönlich begeistert diese Nachricht, auch wenn ich bisher noch nicht mit IDEA gearbeitet habe. Bisher habe ich für meine tägliche Arbeit ausschließlich Eclipse verwendet (wenn man mal von der "guten alten Zeit" absieht, als der Texteditor noch das Mittel der Wahl war). Natürlich wurde bereits in IDEA gestöbert, genauso wie in Netbeans, aber um diese Tools wirklich kennen zu lernen braucht es ein Projekt.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nun sind die drei großen Java-IDEs Open Source. Das beflügelt die Fantasie. Die Eclipse-API ist mir in den letzten Jahren in Fleisch und Blut übergegangen. Und auch wenn es immer wieder Ecken gibt die ich noch nicht besucht habe, all zu viel Neues/Überraschendes/Reizvolles gibt es nicht mehr zu entdecken (zumindest nicht bis &lt;a href="http://www.eclipse.org/e4/"&gt;e4&lt;/a&gt; sich der Fertigstellung nähert). Aber was ist mit den beiden anderen Playern? Jede IDE hat ihre Fangemeinde, jede hat ihre Stärken und Schwächen, jede ist auf ihre Art und Weise Reizvoll.&lt;br /&gt;&lt;br /&gt;Ich brauche ein Projekt das es mir erlaubt mich in die IDEs einzuarbeiten, nicht nur Oberflächlich sondern bis ins Detail, bis in die API, so weit wie möglich. Und was wäre da besser geeignet als ein Plugin, welches für alle drei IDEs funktioniert? Ein solches Programm wird es mir ermöglichen mich sowohl in die Benutzung als auch in die API einzuarbeiten. Und weil ich denke das diese Gedanken/Erfahrungen/Erkenntnisse auch für andere interessant sein werden, werde ich sie teilen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.blogger.com/" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;span id="goog_1255966714060"&gt;&lt;/span&gt;&lt;span id="goog_1255966714066"&gt;&lt;/span&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_dg_hQZkpuBU/StyMpjFCFaI/AAAAAAAAABo/b2tots2ID_U/s320/screen01.png" /&gt;&lt;span id="goog_1255966714061"&gt;&lt;/span&gt;&lt;/a&gt;&lt;b&gt;&lt;span id="goog_1255966714067"&gt;&lt;/span&gt;Die Idee&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.idedeluxe.com/bytecode/"&gt;ByteCodeDeluxe&lt;/a&gt; ist Anfang des Jahres in der Version 0.1 veröffentlicht worden und ich bin recht zufrieden damit. Die Entwicklung hat Spaß gemacht, wie bei jedem Hobby-Projekt lag der Fokus auf der Lernerfahrung. In diesem Fall habe ich angefangen den Java-Bytecode kennen zu lernen. Die Architektur ist gut, die Umsetzung allerdings noch nicht zu hundert Prozent gelungen. Hier habe ich einige Gedanken im Kopf was man besser machen könnte und ich freue mich schon auf die Umsetzung.&lt;br /&gt;&lt;br /&gt;Das also ist der Plan: die Version 0.2 von ByteCodeDeluxe umsetzen. Dabei die neuen Ideen zur Architektur einarbeiten und, ganz wichtig, die Abstraktion so weit treiben, dass der Großteil des Codes sich für drei Plugins wiederverwenden lässt. Eines für Eclipse, eines für IDEA und eines für Netbeans. Welche neuen Features dabei Eingang finden werden, und welche nicht, bleibt noch zu entscheiden. So ganz zufrieden bin ich mit der Bytecode Ansicht noch nicht, und es wäre schön wenn man den Bytecode nicht nur betrachten, sondern auch editieren könnte. Es gibt noch vieles mehr was schön wäre, aber die Versionsnummern sind ja noch nicht aufgebraucht. Und eines wird es mit Sicherheit geben: ByteCodeDeluxe für Eclipse, IDEA und Netbeans!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4981594068570960202-8223590124348767592?l=idedeluxe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://idedeluxe.blogspot.com/feeds/8223590124348767592/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://idedeluxe.blogspot.com/2009/10/drei-plugins-eroffnung.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/8223590124348767592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4981594068570960202/posts/default/8223590124348767592'/><link rel='alternate' type='text/html' href='http://idedeluxe.blogspot.com/2009/10/drei-plugins-eroffnung.html' title='Drei Plugins - Eröffnung'/><author><name>Arne Deutsch</name><uri>http://www.blogger.com/profile/13008494169047863525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_dg_hQZkpuBU/Sttn-GQ4qaI/AAAAAAAAAA8/gCQtbWt9BHY/S220/Bewerbungsfoto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_dg_hQZkpuBU/StyJ8oznctI/AAAAAAAAABg/WrxSLkInonc/s72-c/ides.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
