April 11th, 2010
Jeder Bildschirm in einer nativen Blackberry-Applikation leitet von net.rim.device.api.ui.Screen ab. Das Blackberry-Framework verwaltet die Screens als Stapel (“Stack”): Soll ein Screen geöffnet werden, muss er mit UIEngine.pushScreen(Screen screen) auf den Stapel gelegt werden.
Wird ein Screen geschlossen, wird wieder der darunterlegende Screen dargestellt. Dieses Verhalten entspricht im Übrigen genau dem UINavigationController des iPhone SDKs.
Beim “Pushen” des Screens werden dem Screen diejenigen Objekte übergeben, die er darstellen und verarbeiten muss. Hier ist beim Software-Design zu beachten, dass der Screen nicht das komplette ganze Modell kennt, sondern immer nur den spezifischen Modell-Abschnitt, den er darstellen muss. So wird eine enge Verzahnung der Screens vermieden und ein höherer Wartungs- und Wiederverwendungsgrad erreicht.
Wenn der oberste Screen Änderungen an darunterliegende Screens kommunizieren muss, so sollte dies über ein Interface geschehen, um weiterhin eine lose Koppelung der Screens sicherzustellen. Das nachfolgende vereinfachte Beispiel zeigt dieses Pattern anhand einer vereinfachten Mailapplikation.

- Mit Klick auf “Posteingang” wird ein ListScreen erzeugt und auf den Stack “gepushed”
Auf dem Stack liegen nun zwei Screens (IndexScreen und ListScreen). Der ListScreen hält eine Referenz auf einen Vector mit allen Emails.
- Beim Klick auf eine Email in der Liste wird eine Instanz des DetailScreens erzeugt und auf den Stack gepushed. Diese Instanz erhält eine Referenz auf das darzustellende E-Mail Objekt und den ListScreen über das Interface “DetailScreenListener”.
- Über genau dieses Interface teilt der Detailscreen dem ListScreen mit, wenn der User auf “Löschen” geklickt hat, damit dieser aus der Liste entfernt wird
Dieses Pattern erlaubt flexibel strukturierbare Anwendungen und wird sowohl im Blackberry- als auch in iPhone-Apps eingesetzt.
Posted in Mobile Multiplexer | No Comments »
April 4th, 2010
Mit der steigenden Popularität von Apple-Produkten rückte auch die Programmiersprache “Objective-C” in den Fokus von Software-Entwicklern, da nur mit ihr die Entwicklung von nativen iPod-, iPhone- und iPad-Applikationen möglich ist. Das Faszinierende an dieser Sprache ist die Kombination aus statischer und dynamischer Typisierung:
“Objects are dynamically typed. In source code (at compile time), any object variable can be of type id no matter what the object’s class is. The exact class of an id variable (and therefore its particular methods and data structure) isn’t determined until the program runs. [...] To permit better compile-time type checking, and to make code more self-documenting, Objective-C allows objects to be statically typed with a class name rather than generically typed as id. It also lets you turn some of its object-oriented features off in order to shift operations from runtime back to compile time.”
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocStaticBehavior.html
Konkret bedeutet dies, das beliebige Nachrichten an Objekte verschickt werden können. Mit Hilfe von “Categories” können bestehende Klassen (beispielsweise NSString) sogar um neue Methoden erweitert werden, ohne deren Quellcode zu ändern. Zudem können größere Klassen mit Categories in mehrere Dateien aufgeteilt werden.
Aufgrund des dynamischen Verhaltens kennt Objective-C keine privaten Methoden. Zwar kann auf eine Deklaration der Methode im Interface verzichtet werden, allerdings kann die Methode dennoch aufgerufen werden.
Auch null-Referenzen verhalten sich etwas anders als gewohnt: In Java führt jeder Methodenaufruf einer null-Referenz zwangsläufig zu einer NullPointerException. In Objective-C dagegen wird in diesem Fall nil zurückgegeben, und das ohne Fehlermeldung. Die nil-Referenz hat auch eine weitere Aufgabe: In Listen (NSMutableArray) wird nil zur Markierung des Listenendes verwendet, und kann somit nicht als null-Wert genutzt werden. Für diesen Zweck gibt einen eigenen Typ namens NSNull.
Eine Garbage Collection ist nur für Mac OSX 10.5 verfügbar. iPad-, und iPhone-Entwickler müssen sich dagegen mit dem halbautomatischen Memory-Management anfreunden bzw. auseinandersetzen. Da Objective-C direkt von C ableitet, erbt die Sprache auch einige C-Artefakte wie beispielsweise den für Java-Entwickler ungewohnten Präprozessor.
Trotz dieser Hürden überzeugt Objective-C jedoch mit ihrer spannenden Kombination aus statischer Typisierung und dynamischen Binden. Das Tooling (XCode) kann leider aber noch nicht mit Eclipse mithalten. Hier besteht noch deutlicher Nachholbedarf seitens Apple.
Posted in Jenseits von Java | No Comments »
February 24th, 2010
[Novum heute: Der erste Blogeintrag zu Objective-C bzw. XCode.]
XCode ist Apple’s IDE für die Entwicklung von iPhone und Mac-Applikationen. Allerdings ist XCode bei weitem nicht so komfortabel und mächtig wie Eclipse. Dennoch gibt es ein paar Shortcuts, die jeder iPhone-Entwickler kennen sollte:
1. cmd-shift-d (Springt schnell zu einem File, ähnlich ctrl-shift-r in Eclipse )
2. cmd-alt-up (Wechselt von .h Datei zur passenden .m Datei und umgekehrt)
3. cmd-shift-j (Refactor von Klassen, Methoden und Variablen)
4. ctrl-shift-7 (Springt zum nächsten Platzhalter)
5. cmd-shift-7 (Kommentiert markierten Code)
6. ctrl-k (Löscht aktuelle Zeile)
7. cmd-shift-e (Schaltet den Editor in der Projektansicht ein und aus)
Posted in IDE, Jenseits von Java | No Comments »
January 30th, 2010
Vor kurzem habe ich für ein bereits aufgesetztes Blackberry-Projekt einen automatischen Build für Hudson konfiguriert. Wenn Maven im Einsatz ist, ist das normalerweise schnell gemacht, aber bei diesem Projekt war der Einsatz von Maven nicht möglich. Somit bleibt einem nichts anderes übrig, als selbst ein paar Ant-Skripte zu programmieren. Klar, kein Problem. Allerdings wollte ich nicht die ganzen Projektabhängigkeiten im Ant-Skript wiederholen (DRY und so…), sie wurden ja schon im Eclipse-Projekt konfiguriert.
Aber wie bekomme ich die Informationen aus der .classpath-Datei ?
Hier hilft ant4eclipse: Der “getJdtClassPath”-Task extrahiert den Classpath aus dem Eclipse-Projekt und stellt ihn für die weitere Verwendung in ant bereit. Das nachfolgende Beispiel-Skript nutzt den extrahierten Classpath und kompiliert damit die Java-Klassen:
<?xml version="1.0"?>
<project
name="hudson_build"
basedir="."
default="build"
xmlns:ant4eclipse="antlib:org.ant4eclipse">
<property
name="workspaceDirectory"
value="${basedir}/.." />
<!-- define ant4eclipse tasks -->
<taskdef
uri="antlib:org.ant4eclipse"
resource="org/ant4eclipse/antlib.xml" />
<!-- import the ant4eclipse platform macros -->
<import
file="${basedir}/hudson/ant4eclipse/macros/a4e-platform-macros.xml" />
<!-- import the ant4eclipse jdt macros -->
<import
file="${basedir}/hudson/ant4eclipse/macros/a4e-jdt-macros.xml" />
<target
name="build">
<ant4eclipse:getJdtClassPath
property="classpath"
pathId="classpathref"
workspaceDirectory="${workspaceDirectory}"
projectName="ch.javablog.myproject" />
<!-- classes folder -->
<delete
failonerror="false">
<fileset
dir="classes" />
</delete>
<mkdir
dir="classes" />
<javac
srcdir="src"
destdir="classes"
classpathref="classpathref"
target="1.1" />
</target>
</project>
Praktisch.
Posted in IDE | No Comments »
January 22nd, 2010
Wesentliche neue Features:
- Erklärungstext für jede Frage
- Verbesserte Listendarstellung in “MyList”
- Und ganz wichtig: Schickeres Applikationsicon
Hier gehts zum Download. Viel Spaß beim Lernen.
Posted in jPrep - SCJP training | 1 Comment »
November 30th, 2009
Eigentlich ist es ganz einfach. Aber es wird dennoch häufig vergessen. Die Rede ist vom “Expire” HTTP-Header. Er gibt dem Webbrowser zu erkennen, ab wann eine Resource “veraltet” ist. Typischerweise werden diese Header im Webserver konfiguriert (und nicht in der eigentlichen Applikation). Hier ein Beispiel aus einer Apache HTTP Konfiguration, die dafür sorgt, dass alle statische Komponenten nach einem Tag “veralten”.
<LocationMatch "^/static(.*)">
ExpiresActive On
ExpiresDefault "access plus 1 day"
</LocationMatch>
Allerdings besteht die Gefahr, dass Codeänderungen aufgrund des clientseitigen Caches beim Kunden erst sich nach einem Tag manifestieren. Eine Lösung ist, den Resourcen einen Timestamp des Deployments zu geben, so dass sie quasi endlos gecached werden können. Bei einem neuen Deployment erhalten die Resourcen einen neuen Timestamp. Mehr zu Frontend Best Practises gibts hier.
Posted in Infrastruktur | No Comments »
September 13th, 2009
Zur Qualitätssicherung eines Softwareprojekts gehören neben Unittests auch statische Codeanalysen. Tools wie Checkstyle, Findbugs oder PMD untersuchen Java-Klassen und bewerten den Code anhand verschiedener Metriken.
Zwar können diese Checks einen manuellen Codereview nicht ersetzen, aber Standardfehler und bekannte Anti-Patterns werden zuverlässig erkannt. Für jedes der genannten Tools gibt es ein Eclipse-Plugin, das die betreffenden Codestellen markiert. Die Anzeige der Fehler ist aber nicht ausreichend: Bei schwerwiegenden Verstössen soll auch der Build scheitern, ansonsten besteht die Gefahr, dass der Code nicht korrigiert wird. Aber wie kann man das umsetzen ?
Mit Maven 2 geht dies einfach mit einer Plugin-Konfiguration innerhalb des “build”-Elements.
Hier ein Projektbeispiel für die PMD Analyse:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<sourceEncoding>${file.encoding}</sourceEncoding>
<minimumTokens>100</minimumTokens>
<targetJdk>${java.target.version}</targetJdk>
<failOnViolation>true</failOnViolation>
<failurePriority>2</failurePriority>
</configuration>
<version>${pmd.version}</version>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Mit dieser einfachen Konfiguration wird sichergestellt, dass der Code keine PMD-Verstösse der Kategorie 1 und 2 enthält. Zudem ist garantiert, dass der Build bei Copy&Paste von 100 Wörtern (bzw. Tokens) scheitert. Praktisch !
Posted in Maven | No Comments »
August 29th, 2009
Wenn Bibliotheken von Drittherstellern nicht vollständig dokumentiert sind, und dann auch noch der Quelltext fehlt, kann ein Decompiler Abhilfe schaffen. Leider wurde die Entwicklung des kostenlosen Decompilers “JAD” von Pavel Kouznetsov eingestellt.
Seit letztem Jahres steht eine Alternative namens “JD” ebenfalls kostenlos zur Verfügung. Das Projekt ist zu finden unter http://java.decompiler.free.fr/ und bietet neben einer schicken Standalone GUI-Version auch ein Eclipse-Plugin an. Obwohl es noch nicht ganz fertig ist, hinterlässt das Tool einen sehr guten Eindruck.
Posted in IDE | 2 Comments »
July 18th, 2009
Apache Maven ist ein fantastisches Buildsystem, allerdings sind manche Plugins eher spartanisch dokumentiert. Für mehr Klarheit sorgt das maven-help-plugin mit seinem “describe“-goal, welches alle Goals eines Plugins inkl. der möglichen Parameter beschreibt. Beispielaufruf:
mvn help:describe -Dplugin=org.codehaus.mojo:findbugs-maven-plugin -Dfull
Ebenso hilfreich ist das “effective-pom“-goal, mit dem ein POM inkl. aller geerbten Eigenschaften ausgegeben wird. Vor allem bei grossen Projekten mit vielen Parents ist die generierte Übersicht hilfreich. Beispiel:
mvn help:effective-pom
Posted in Maven | No Comments »
June 20th, 2009
In der letzten Zeit gabs weniger Posts im Blog. Dies hatte auch einen Grund: jPrep. Seit ein paar Monaten beschäftige ich mit der Entwicklung von iPhone / iPod touch Applikationen. Die erste habe ich nun auf den Appstore gestellt.
jPrep ist ein Vorbereitungstool für die SCJP 6 (Sun Certified Java Programmer) Zertifizierung. In Form eines Quiz mit 175 Fragen wird der Anwender auf die Prüfung vorbereitet. Eine übersichtliche Statistik zeigt Stärken und Schwächen in den einzelnen Themengebieten auf. Als zusätzlichen Feature können die Quizfragen zu einer eigenen Merkliste (“MyList”) hinzugefügt werden. Für die meisten Fragen habe ich einen direkten Link auf die Java Reference (API oder die Java Language Specification) eingepflegt, der über den (applikationsinternen) Browser geöffnet werden kann. Hier ein paar Screenshots:
Themenübersicht
Beispielfrage
Statistik
MyList
Umgesetzt wurde es komplett mit Objective-C. Als Java-Entwickler muss man sich zwar an manche Besonderheiten der Sprache und der IDE erst mal gewöhnen, aber wenn diese Hürde geschafft ist, macht iPhone-Entwicklung richtig Spass. Apropos Spass: Für die Pflege der Fragen habe ich eine eigene Webapplikation mit Ruby On Rails geschrieben. Ging definitiv schneller als mit Java
Posted in jPrep - SCJP training | 6 Comments »