Im Grunde bin ich mit Java als Sprache und als Plattform ganz zufrieden. Hier und da kann es Verbesserungen geben. Beispielsweise in der Abschottung von Subsystemen. Dies hätte ich gerne in Form eines Modulsystems und nicht als OSGi-System aufgepfropft. Bei Generics hätte einiges besser laufen können. Mit Java 7 wird jetzt immerhin der Diamond-Operator eingeführt. Autoboxing ist leider vollkommen verunglückt.
Womit ich inzwischen nicht mehr zufrieden bin ist das Schlüsselwort final und seine Semantik. Mit final wird eine Klasse oder Methode vor überschreiben geschützt. Ein Feld wird vor erneuter Zuweisung geschützt. Das Feld ist dementsprechend mehr eine Konstante als eine Variable. Langjährige Erfahrung hat allerdings gezeigt: überschreiben oder neu zuweisen wird überbewertet. Vererbt wird selten wirklich sinnvoll und echte Variablen gibt es auch eher selten.
Inzwischen halte ich es für eine bessere Idee statt final ein var zu verwenden. Also Verbung und neu zuweisen nicht explizit zu verbieten, sondern explizit zu erlauben. Code würde dadurch robuster werden. Einige sich immer wieder einschleichender Fehler würden beseitigt. Überkomplexe Vererbungshierarchien mehr durchdacht, bevor sie in Code gegossen werden. Einige der neuen Sprachen, die auf der JVM aufsetzten, implementieren var. Leider nicht die Hauptsprache Java. Schade, dass der Zug dafür abgefahren ist.
Lose, unausgereifte Gedanken.
Geräte werden immer kleiner und wir tragen immer mehr elektronische Gadgets mit uns herum. Das Telefon mit Touchoberfläche, MP3-Player und ein Netbook. Zu Hause ein Notebook oder ein Tablet der IPad-Klasse. Eventuell eine Kamera. Zwischen allen wollen Daten hin- und her kopiert werden. Das ist immer noch ziemlich kompliziert.
Eine Idee über die wir uns als Techniker einmal Gedanken darüber machen sollen ist, ein geräteübergreifendes Cut'n'Paste und Drag'n'Drop zu implementieren. Das kann über unterschiedliche Austauschmechanismen geschehen. Sei es ein zentraler Server unterstützt das kopieren zwischen den Gadgets oder es geschieht über Nahbereichsfunktechniken wie zum Beispiel Bluetooth/WLAN bzw. Kabel gebunden (z.B. USB). Ein nicht unwichtiges Feature dabei ist, dass die Ausrichtung der Geräte zueinander bekannt ist. Nur so lässt sich ein intuitives System für den Benutzer schaffen. So kann beispielsweise durch einfaches wegwischen mit dem Finger auf einer Touchoberfläche in Richtung des Empfängergerätes der Transfer initialisieren. Wird beispielsweise eine Datei rechts aus den Bildschirm herausgewischt und das Empfängergerät ist ebenfalls rechts vom Sender, so muss die kopierte Datei links auf dem Empfängergerät herein fliegen. Würde das Symbol der Datei rechts herein fliegen würde dies unglaubwürdig sein. Entsprechend darf kein Gerät die zu kopierende Datei in Empfang nehmen, wenn in die Richtung keine Gerät vorhanden ist. Diese Ortbestimmung ist sicherlich einer der kniffeligsten Punkte.
Alternativ kann ich mir auch eine einfache erste Lösung vorstellen. Das Empfängergerät wird ähnlich dem Mac OS Dock am Rand des Sendergerätes eingeblendet. Dies muss natürlich auch in laufenden Applikationen möglich sein. Auf diese Einblendung wird dann das zu zu kopierende Artefakt verschoben. Es erscheint dann auf dem Empfängergerät. Eventuell kann hier noch ein Menu geöffnet werden, um eine Empfangsapplikation heraus zu bestimmen.
Wichtig ist, dass die Protokolle plattformübergreifend sind. Geräte und Plattformen diversifizieren immer weiter. Implementiert ein Plattformhersteller eine solche Umgebung nur für seine Plattform, dann wird eine solche Insellösung Kunden nur wenig überzeugen. Allerdings habe ich wenig Hoffnung, dass der Wunsch des plattformübergreifens wirklich gleich umgesetzt wird.
Der neue biometrische Personalausweis ist dass sicherste Dokument auf Erden. Total fälschungssicher und perfekt für E-Commerce und was sonst noch alles geeignet. Mit elektronisch auslesbarem Passbild und auf Wunsch mit Fingerabdruck (den Sinn habe ich noch nicht verstanden). Und weil das Ding so superduper sicher, toll und innovativ ist, verschenkt der Bund Geräte zum auslesen der Daten. Damit Otto Normalverbraucher auch was davon hat; die ganzen tollen Features auch nutzen kann. Aber das tolle verschenkte Auslesegerät ist prinzipiell unsicher. Das weiss auch der Verschenker.
Und mir muss jetzt nur noch erklärt werden, wieso wir einen so tollen, total fälschungssicheren Personalausweis brauchen (war das nicht auch bei der letzten Version die Begründung?) und dann total unsichere 1,5 Millionen Auslesegeräte verteilen?
So kann es gehen. Nur mal kurz Urlaub beantragen wollen. Dabei soll EDV doch Zeit sparen.
Ein schönes Bespiel für das Problem mit klaren Begriffen: Was ist geistiges Eigentum im Kontext von Urheberrecht und Patentrecht? Welches Recht dominiert? Im Fall von Softwarepatenten würde dieses Patentrecht mein Urheberrecht an einer konkreten Lösung aushebeln.
Klare Sprache. Seit 2.500 Jahren. Auch einer der Gründe, es damals nicht funktionieren konnte. Der Meister hat ständig neue Namen erfunden und/oder ihnen neue Bedeutung gegeben. Obwohl… Meister…? Wohl eher nicht.
Dsï Lu sprach: »Der Fürst von We wartet auf den Meister, um die Regierung auszuüben. Was würde der Meister zuerst in Angriff nehmen?«
Der Meister antwortete: »Unbedingt die Namen richtigstellen.«
Darauf Dsï Lu: »Darum sollte es sich handeln? Da hat der Meister weit gefehlt! Warum denn deren Richtigstellung?«
Der Meister entgegnete: »Wie ungebildet du doch bist, Dsï Lu! Der Edle ist vorsichtig und zurückhaltend, wenn es um Dinge geht, die er nicht kennt.
Stimmen die Namen und Begriffe nicht, so ist die Sprache konfus. Ist die Sprache konfus, so entstehen Unordnung und Mißerfolg. Gibt es Unordnung und Mißerfolg, so geraten Anstand und gute Sitten in Verfall. Sind Anstand und gute Sitten in Frage gestellt, so gibt es keine gerechten Strafen mehr. Gibt es keine gerechten Strafen mehr, so weiß das Volk nicht, was es zu tun hat und was es lassen soll. Darum muß der Edle die Begriffe und Namen korrekt benutzen und auch richtig danach handeln können. Er geht mit seinen Worten niemals leichtfertig um.«
(Konfuzius, Gespräche ⅩⅢ, 3)
Wie bei DOS 1.0 kam ich mir vor. Ich wollte Fotopapierabzüge von Bildern machen. Im Media-Markt am Alex. Die Bilder hatte ich auf einem simplen USB-Stick dabei. Also eingesteckt am Fuji-Film Automaten und… ich traute meinen Augen nicht. Ihr müsst wissen, auf dem Stick sind knapp 6 GB Daten – in über 400 Verzeichnissen. Der Fuji-Film Automat zeigte mir alle Verzeichnisse an, untereinander. Nicht die Top-Level Verzeichnisse, durch die ich mich dann durch navigieren kann – das sind nur 8 gewesen. Nein, alle. Sortiert nach… das Schema habe ich nicht heraus gefunden. Auf jeden Fall nicht alphabetisch. Die Liste hat auch keinen Slider, um einfach zu scrollen. Nein, um einen Eintrag zu überspringen musste jeweils ein Knopf geklickt werden. Die Verzeichnisse wurden auch nicht mit vollem Namen angezeigt, sondern in verkürzter 8.3 Schreibweise. VFAT? Was ist das?
Okay, ich war da, ich wollte meine Bilder. Also knapp 120 mal auf diesen blöden Knopf gedrückt – nennt mich dämlich; akzeptiert. Verzeichnis gefunden. Allerdings, die Bilder aussuchen war von genauso intuitiver Bedienung. Als ich zwei ausgewählt habe – wie auch immer – habe ich einmal zuviel "zurück" geklickt. Und was soll ich euch schreiben? Ich landete wieder in der Auswahlliste der Verzeichnisse. Natürlich hat sich diese grandiose, sagenhaft intuitive Fuji-Film Automatensoftware nicht die Position gemerkt. Nope. Alles zurück auf Los. Dazu verurteil, noch einmal 120 mal auf den Button zu klicken? Ich habe das Urteil fluchend abgelehnt.
Ich bin als Softwareentwickler selbst kein Genie in intuitiven UIs. Aber sowas hätte selbst ich besser hinbekommen. So ein Bediendkonzept war schon vor 20 Jahren Benutzern nicht mehr zuzumuten. Geschweige denn an einem anonym zu bedienenden Automaten, mit dem auch Lieschen Müller ihr Fotos ausdrucken will.
Ich versuchs jetzt mal mit einem Online-Shop.
Flash ist in die Webseite eingebunden. Für irgend eine Werbung. Diese wird zwar vom Gehirn ausgeblendet, nicht jedoch vom Prozessor. Der lief heiss. So heiss, dass die Lüfter zur Höchstform aufliefen. Als Übeltäter war exakt diese Flash Applikation zu identifizieren. Und leider ist sowas nicht zum erstenmal passiert.
Es war keine leichte Entscheidung. Über Werbungen werden immerhin die meisten kommerzielle Webangebote finanziert – mehr oder weniger. Trotzdem: ich habe jetzt eine Flashblocker installiert. Wer nicht hören will muss fühlen. Durch geringere Werbereichweite.
Der Schockwellenreiter baut gerade sein eigenes Streetview. Er experimentiert damit die Bilder mit OpenStreetMap Karten anzuzeigen. Ich wollte das auch schon immer mal mit meinen geotaggt Bildern machen – war nur zu träge. Dabei habe ich einen etwas anderen Weg als Jörg Kantel gewählt. Einen Weg der etwas weniger strikt mit <body onload='…'> umgeht. So wie er es beschreibt geht es bei mir nicht ganz. Die <div> ID würde bei dieser Blogsoftware einer globalen Variable entsprechen. Da ich eventuell mehr Maps einbinden möchte starte ich die Map innerhalb eines <script> Bereichs im Body. Das ist mehr der Weg, wie es die OpenLayers Implementierung von OpenStreetMap aktuell macht.
Daneben untersuche ich noch eventuelle URL Parameter. Sind sie nicht gesetzt, werden Default-Werte verwendet. Hierfür wird eine kleine Funktion auf RegExp Basis verwendet. Grund: ich wollte für diese inzwischen fünf Jahre alte Software kein Plugin mehr schreiben. Mit den Parametern lässt sich die Map weitestgehend steuern.
<div id='berlin_picture_map_20100612' style='height:480px; width:640px; '></div>
<script type="text/javascript" defer="defer">
// <!--
// Possible request parameters:
// div = name of the "div" ID for the map.
// Default: "berlin_picture_map"
// lon = center longitude of the map. If available also "lat" must be available.
// Default: 13.44989
// lat = center latitude of the map. If available also "lon" must be available.
// Default: 52.50776
// z = OpenStreetMap zoom level.
// Default: 12
// tsv = Name and path of the TSV file. Will be concatenate with the value of "url".
// Default: http://www.speexx.de/blog/files/openstreetmap/ol/"
// url = Base URL of the TSV file. Will be concatenate with the value of "tsv".
// Default: "berlin/berlin.tsv"
var baseUrl = "http://www.speexx.de/blog/files/openstreetmap/ol/";
var baseLat = 52.50776;
var baseLon = 13.44989;
var baseZoom = 12;
var baseDiv = "berlin_picture_map_20100612";
var baseTsv = "berlin/berlin.tsv";
var map;
function mapInit() {
var map_div = gup("div");
if (map_div == "") {
map = createMap(baseDiv);
} else {
map = createMap(map_div);
}
}
function createMap(divName) {
var lon = gup("lon");
if (lon =="") {
lon = baseLon;
}
var lat = gup("lat");
if (lat =="") {
lat = baseLat;
}
var zoom = gup("z");
if (zoom =="") {
zoom = baseZoom;
}
var proj4326 = new OpenLayers.Projection("EPSG:4326");
var projmerc = new OpenLayers.Projection("EPSG:900913");
var lonlat = new OpenLayers.LonLat(lon, lat);
var map = new OpenLayers.Map(divName, {
controls: [
new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.MouseDefaults(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.Attribution()],
maxExtent:
new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
numZoomLevels: 18,
maxResolution: 156543,
units: 'm',
projection: projmerc,
displayProjection: proj4326
});
var mapnik_layer = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
var tah_layer = new OpenLayers.Layer.OSM.Osmarender("Tiles@Home");
map.addLayers([mapnik_layer, tah_layer]);
var tsv = gup("tsv");
if (tsv == "") {
tsv = baseTsv;
}
var tsvUrlPrefix = gup("url");
if (tsvUrlPrefix == "") {
tsvUrlPrefix = baseUrl;
}
var tsvUrl = tsvUrlPrefix + tsv;
var berlin_pic_layer = new OpenLayers.Layer.Text("Berliner Bilder", {
location: tsvUrl, projection: map.displayProjection});
map.addLayer(berlin_pic_layer);
lonlat.transform(proj4326, projmerc);
map.setCenter(lonlat, zoom);
}
// from http://www.netlobo.com/url_query_string_javascript.html
function gup(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null) {
return "";
} else {
return results[1];
}
}
mapInit();
// -->
</script>
Ist noch nicht hundertprozentig, tut aber für micht.
Ich habe einen TAB separierte Datei erstellt. In der sind einige Berlin Bilder hinterlegt. Zur Zeit noch mit absoluten URLs. Muss mal schauen, ob ich das auch relativ machen kann. Bin jetzt aber zu müde dazu. Das Ergebniss sieht zusammen dann so aus:
Aber was ist guter Code? Und wer entscheidet das? Einfache Antwort: Immer derjenige, der die Dokumentation braucht. Das ist regelmässig nicht derjenige, der die Dokumentation (oder den Code) geschrieben hat.
Diejenigen, die dokumentieren, überschätzen sich regelmässig selbst. Leider.
