Archive for 'Developers Corner'

Das Has-Pattern

Möglicherweise hat dieses Pattern bereits einen anderen Namen, oder es ist gar nicht erwähnenswert genug, um einen Namen zu erhalten.
Dennoch werde ich immer mehr ein Freund davon.

Als HasPattern verstehe ich Functions oder Properties, die eine Abfrage der Form “sind Elemente der Form X verfügbar” darstellen. Der Name des Patterns leitet sich aus dem Präfix der Methoden ab, den sich alle diese teilen: “HasItems”, “HasClients”, “HasListItems” etc.

Beispiel:

Gegeben ist ein Objekt “Employer” (Arbeitgeber), das eine Auflistung von Angestellten enthält:

C#:

public class Employer {
    public IEnumerable Employees() {
        return …;
    }
}

PHP:

class Employer {
    public function Employees() {
        return $this->employees;
    }
}

Nun besteht oftmals nicht nur die “Herausforderung”, alle Angestellten des Arbeitgebers zu durchsuchen, oder die Anzahl der Angestellten auszugeben. Nicht selten will ein Entwickler einfach nur wissen: “HAT dieser Arbeitgeber überhaupt Angestellte?”

Viel zu häufig bin ich über Code gestolpert, der einfach die Anzahl der Elemente in einer Auflistung auswertet. Ist count > 0, hat der Arbeitgeber offensichtlich angestellte:

C#:

Employer emp = …;
if(emp.Employee.Count() > 0) {
    // dieser Arbeitgeber hat Angestellte
} else {
    // dieser Arbeitgeber hat keine Angestellte
}

PHP:

$emp = $this->getEmployerById(42);
if( count($emp->Employees()) {
    // dieser Arbeitgeber hat Angestellte
} else {
    // dieser Arbeitgeber hat keine Angestellte
}

Dieser Weg ist so unelegant wie nur möglich. Letztendlich werden alle Elemente durchgezählt, nur um herauszufinden, ob mindestens ein Element vorhanden ist. Richtig?
Tatsächlich kann das Zählen aller Elemente einer Auflistung richtig teuer sein! Natürlich, die List-Klasse vom .NET-Framework oder PHP’s Arrays wissen, wie viele Elemente sie aktuell verwalten. Bei abstrakteren Datenhaltungsstrukturen sollte davon aber nie ausgegangen werden!

Die LINQ-Extensions von .NET z.B. bieten zwar die tolle Methode Count() als Erweiterung zu allen IEnumerables. Diese zählt aber tatsächlich alle Elemente einzeln durch, in dem es via GetEnumerator() den zugehörigen Enumerator holt und dort mit MoveNext() durch alle Elemente iteriert und dabei eine Variable hochzählt. Diese enthält das Ergebnis von Count().

Richtig gefährlich werden kann es bei OR-Mappern: wenn hier dank Lazyloading erst noch Elemente nachgeladen werden – und zwar ALLE -, bekommen die Entwickler nach der Markteinführung richtig Freude.

Natürlich ist es ein schlechter OR-Mapper, der erstmal alle Datensätze lädt, um diese zu zählen. Aber als Konsument derartiger Strukturen wollen wir uns nicht auf die Implementierung selbiger verlassen, sondern ganz smart mit der Schnittstelle kommunizieren.

Darüberhinaus, rein vom sprachlichen und dokumentatorischen her, bietet es sich in meinen Augen an, einer solchen Auflistungs-Methode gleich noch eine Has-Methode zu spendieren:

C#:

public class Employer {
    public IEnumerable Employees() {
        return …;
    }

    public bool HasEmployees() {
    return … // true/false/Employees.Any() etc.;
    }

}

PHP:

class Employer {

    public function getEmployees() {
        … ///
    }

    public function hasEmployees() {
    }

}

WIE die Methode “hasEmployees” nachher implementiert ist, spielt keine Rolle und ist uns als Konsument dieser Klasse egal. Tatsächlich gegen wir davon aus, das die Entwickler der Klasse Employer den besten und performantesten Weg kannten und entsprechend implementiert haben.

Wie ließt sich denn der daraus folgende Code?

Ließt sich
     “if($employer->hasEmployees) echo “(*)”;”

nicht auch besser als

    “if( count($employer->getEmployees()) > 0) echo “(*)”” ?

In ersterem Fall wissen wir direkt, was der Entwickler wirklich wissen will. Und was er nicht wirklich wissen will. Er muss nicht die tatsächliche Anzahl der Employees wissen. Er will nur wissen: ist mindestens einer vorhanden?

Der aufmerksame Leser wird zumindest im .NET-Bereich an die Linq-Methode “Any()” erinnern wollen. Sie ist relativ stromsparend implementiert, in etwa so:

public bool Any(this IEnumerable items) {
    foreach(var item in items) {
        return true;
    }
    return false;
}

Aber auch hier setzen wir wieder auf eine “fremde” Implementierung von “außen”, die das Konstrukt, das sich hinter “items” befindet, nicht kennt. Es wird der Enumerator zu items erzeugt, falls noch nicht vorhanden, und wir verwenden diesen nicht zum enumerieren, sondern zum Auswerten.
Auch hier finde ich es charmanter, direkt auf eine “hasItems”-Methode zurückgreifen zu können, die eventuell sogar intern performanter ausgewertet werden kann, z.B. durch die Zurückgabe einer boolschen Variable, die zu einem Zeitpunkt gesetzt wird, an dem das Objekt definitiv weiss, ob es entsprechende Unterlemente bzw. Detailobjekte enthält oder nicht.

If you need to convert all tables of a database from MyISAM (or somewhat else) to InnoDB, you can use the following Shell-Skript (Download-Link ):

#!/bin/sh

for tbl in `cat tables`
do
echo “ALTER TABLE \`$tbl\`  ENGINE = InnoDB ”
done

Please take care! Backup your database first!

Now we want to create a list containing all Tables of a specified database. At shell prompt, execute the following line:

mysql -uUSER -pPASSWD -D DATABASE_NAME -e ‘SHOW TABLES’ > tables

To process all tables, type in the following command into shell prompt:

mysql -uuser -ppasswd -D database < `convert_to_innodb.sh`

Thats all.

Native Typ-Erweiterung in C#

Seit C# 3.0 können DotNets eingebaute native ValueTypes wie int, string und double um neue Methoden erweitert werden, ohne die Definition der zugrundeliegenden Klassen ändern zu müssen. Diese sogenannten Extension-Methoden können so aufgerufen werden, als währen sie Member-Methoden der Klasse. Ähnliche Konzepte sind mir mal bei Ruby über den Weg gelaufen. Natürlich kann dieses Verfahren auch auf eigene Typen angewandt werden. Extension Methods sind nicht auf eingebaute Typen beschränkt.

Beispiel:

Wir wollen den eingebauten Typ “Integer” um eine Methode “sqr” erweitern, die das Quadrat des Wertes ermittelt und zurück gibt. Die Notwendigkeit dieses Beispiels sei einfach mal dahin gestellt. Es ist lediglich ein Beispiel:

public static class IntErweiterung
{
public static int sqr(this int i)
{
return i * i;
}
}

Mit dieser statischen Klasse wird folgendes möglich:

Console.WriteLine(20.sqr()); //  400
int x = 5;
int y = x.sqr();
Console.WriteLine(y); // 25

Hier stellt sich mir die Frage, warum es dann das Schlüsselwort sealed gibt, mit dem man eine Klasse versiegeln kann, um zu verhindern, das sie überschrieben wird. Vermutlich liegt der Unterschied zwischen der Verberung von Klassen und der Erweiterung via Extension Methods darin, das Extension Methods nur auf öffentliche Member zugreifen können. Damit wäre dann der Sinn einer versiegelten Klasse auch wieder hergestellt.

Probieren wir es einfach mal aus:

public class test
{
int m_i;
public test(int i)
{
m_i = i;
}
 
}
 
public static class testExtension
{
public static int getI(this test i)
{
return i.m_i;
}
}

Wir versuchen hier, die Klasse test um die fehlende öffentliche Methode “getI” zu erweitern, die den privaten Member “m_i” zurück geben soll.

Der Compiler sagt: “Der Zugriff auf “linqtest.test.m_i” ist aufgrund der Sicherheitsebene nicht möglich.

Na dann ist die Weltordnung wieder hergestellt. Extension Methods können die Architektur einer Software zumindest dann ein wenig vereinfachen, wenn ein Wrapper oder ein Adapter geschrieben werden müsste, um eine bestehende nicht-vererbbare Klasse um neue Methoden zu erweitern.

Die Privacy bzw. die Integriät einer Klasse bleibt also gewährleistet. Extension Methods können nur auf öffentliche Member zugreifen und können u.a. dazu benötigt werden, DesignPatterns wie Adapter wieder aufzulösen (wenn man dies denn möchte).

Lambda und LINQ

Eine der großartigen Neuerungen im Sprachumfang von C# bzw. .NET 3.5 sind Lambda und LINQ.

Lambda erinnert mich einerseits an DEFINES von Ansi C, und andererseits an die sog. “Functors” von C++ und wurden hier vermutlich auch abgeguckt. Dennoch wurde Lambda integrativer gelöst, da ein Lambda-Ausdruck direkt innerhalb des Codes erfolgen kann, wo er benötigt wird. C++ – Functors wurden bzw werden i.d.R. als separate Klassenrümpfe mit einem überladenen operator() definiert.

Ein Lamda-Ausdruck sieht zum Beispiel so aus:

Func<int , int> sqr = x => x * x;
Console.WriteLine(sqr(10)); // Result: 100
</int>

LINQ (Abkürzung für Language INtegrated Query) ist eine Komponente von Microsofts .NET-Framework, mit der SQL-, XLink- und XQuery-Anfragen direkt in .NET-Programmiersprachen wie C# 3.0 oder VB.Net 9.0 als Code statt als String eingebunden werden können. LINQ wurde federführend von Turbo-Pascal- und C#-Autor Anders Hejlsberg entwickelt.

LINQ erweitert C# u.a. um direkte Selektion von Datenmengen innerhalb des Codes. Es wird keine Query in String-Form abgesetzt, sondern unmittelbar in dem Code integriert.

Am besten erklärt sich LINQ ein einem kleinen, konkreten Beispiel:

string[] names = { "Faust", "Peter", "Tom", "Fred", "August" };
var foundNamesAsQuery = from s in names
                        where s[0] == 'F'
                        select s;
foreach (string name in foundNamesAsQuery) Console.WriteLine(name);
// Result: Faust, Fred

Wenn LINQ schon in einer SQL-Syntax Datenmengen selektieren und filtern kann, unterstützt es dann auch Sortierungen à la “ORDER BY”? Mal gucken:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace linqtest
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] names = { "Faust", "Peter", "Tom", "Fred", "August" };
            var foundNamesAsQuery = from s in names
                                    where s[0] == 'F'
                                    orderby s descending
                                    select s;
            foreach (string name in foundNamesAsQuery) Console.WriteLine(name);
            Console.ReadLine();
 
        }
 
    }
}

.NET-Betrachtungen

Nach Jahren aktiv gelebter Windows-Ignoranz habe ich mich in den letzten Wochen wieder verstärkt mit Microsofts Windows .NET beschäftigt. Re-Angefixt wurde ich vor allem durch Mono 2.0 , der platformunabhängigen Implementierung von GNOME-Mitbegründer Miguel de Icaza, welche vor kurzem veröffentlicht wurde.

Ich muss ganz ehrlich zugeben, das ich ziemlich erstaunt war über die Weiterentwicklung von .NET. Zu “meiner Zeit” schrieb man die Version 1.1. bzw 2.0.  Inzwischen sind die Jungs bei 3.5 angekommen. Man möge mich jetzt steinigen (Anm.d.Red.:ich werde auch vorläufig nicht mein Linux von der Notebook-Platte putzen),
Continue reading…

String-Klasse in C++

Im Jahre 2003 habe ich eine String-Klasse für C++ gebaut, welche für Non-STL-Environments geschaffen wurde. Die std::string der STL weisst zwar bereits enorme Features auf, meine Ansprüche an eine String-Klasse gingen aber um einiges darüber hinaus. Hinzu kam, das der Maintainer der damaligen Software-Suite kein Freund von fremden Bibliotheken war, und eigene Lösungen bevorzugte.

Also setzte ich mich einige Abende an den Rechner und schuf dieses kleine Werk, was wirklich Spaß auf der einen Seite brachte, als auch genug Erfahrungen mit C++ – templates auf der anderen Seite.

Anbei der Source-Code:


Continue reading…

Super Code…

Auszüge aus einem kürzlich eingekauften Code einer Agentur, die sich als Typo3-Spezialist schimpft:

 if ( $output[count($output)-1]['data'][count($output[count($output)-1]['data'])-1]['num_live'] &lt; $output[count($output)-1]['num_tokens'] )

Die ezCompoents liefern einige nette Authentifizierungstools mit, welche sich durch eigene Filterklassen erweitern lassen.

Speziell die Authentifizierung gegen eine Datenbank (User-Tabelle) prüft auf Übereinstimmung bei Username und Password. Manchmal will man aber auch ein weiteres Feld überprüfen, zum Beispiel, ob der User seine Anmeldung bereits bestätigt hat. Denkbar wäre ein ENUM-Feld namens State mit den Werten "unconfirmed", "confirmed", "suspended", "closed". Nur User mit dem State "confirmed" sollen sich auch tatsächlich einloggen dürfen.

Nachfolgend überschreiben wir die Klasse ezcAuthenticationDatabaseFilter, um neben Username und Password gegen ein beliebiges drittes Feld authentifizieren zu können.


Continue reading…

Zeitreise 1996: Datumsklasse

Süß. Der Streifzug durch die Festplatten vergangener Tage fängt allmählich an, richtig Spass zu machen.

Ich habe eben eine Pascal-Unit gefunden, die ich 1996 schrieb, um mir Datumsberechnungen zu erleichtern. Hierin finden sich einige recht sinnvolle Umsetzungen von Klassen und Funktionen zum Thema Datum und Zeit. Außerdem habe ich noch das hier gefunden: waschechter 16bit Assembler!


Continue reading…

Attribute in C++

Attribute in C# sind eine feine Sache. Wer sie in C++ nutzen möchte, wird seitens des Compilers nicht unterstützt.

Nun gilt es freilich zuzugeben, das die Sprache C++ als solche nicht durch wenige Handgriffe derartig erweitert werden kann. Um jedoch auf den eigentlichen Zweck dieser Attribute in C++ nicht verzichten zu müssen, kann man sich mit einigen Tricks und generischer Programmierung helfen.

Ich habe 2003 einige Template-basierte C++-Klassen entwickelt, die das Problem angehen. Mittels defines könnte man hier fortsetzen, um einen größeren Komfort bereitzustellen.


Continue reading…