Programmiererpraxis

Multiparadigmatisches .NET, Teil 10: Wahl des Ansatzes

Ted Neward

Ted NewardIn meiner last Rubrik (Teil 9 dieser Serie) habe ich die Vermutung geäußert, dass immer dann, wenn sich eine Artikelserie dem zweistelligen Zahlenbereich nähert, der Autor entweder so überheblich ist, anzunehmen, dass seine Leser tatsächlich in diesem Ausmaß an dem Thema interessiert sind, oder einfach zu dumm, ein neues Thema anzubringen. Die Leser müssen dann mutmaßen, welcher der beiden Fälle hier zutrifft.

Dennoch ist durch Rückmeldungen aus der Praxis klar geworden, dass trotz der Gefahr, die mit dem Wechsel ins zweistellige Gebiet verbunden ist, wohl ein weiterer Artikel zum multiparadigmatischem Entwurf notwendig ist, um alle einzelnen Elemente zusammenzubringen, nämlich um zu demonstrieren, wie jedes dieser unterschiedlichen Paradigmen genutzt wird und welches jeweils für eine reale Problematik geeignet ist. "Real" bedeutet in diesem Zusammenhang komplex genug, um aufzuzeigen, wie der Ansatz für Probleme genutzt werden kann, die schwieriger sind als die Beispiele, die in einem Zeitschriftenartikel zur Lösung dargestellt werden.

Der Versuch, ein solches Problem darzustellen, stellt sich als schwieriger als erwartet heraus. Entweder ist die Idee zu kompliziert und weist zu viele Zerstreuungen auf, um ein klares Bild der angewendeten Lösung zu ermöglichen, oder die Idee ist zu einfach und bietet zu wenig Variationsmöglichkeiten bei deren Umsetzung, um zu zeigen, wie die unterschiedlichen Paradigmen jeweils zur Problemlösung eingesetzt werden können. Für die ersten Schritte können wir glücklicherweise von Arbeit profitieren, die bereits gemacht wurde, und zwar in Gestalt des Artikels "Code Katas" von Dave Thomas.

Code Katas

Auf seiner Website (http://codekata.pragprog.com), schildert Thomas, wie er einmal seinen Sohn Zachary zum Karatetraining begleitete, wo er feststellen musste, dass im Zuschauerbereich der Trainingsanlage kein Platz mehr für ihn war. Auf diese Weise hatte er 45 Minuten Zeit für sich selbst zur Verfügung, und er begann, mit einem Code herumzuspielen, an dessen Leistungsauswirkungen er beiläufig gedacht hatte. Er schreibt:

Ich wollte einfach mit Code spielen und mit einer Technik experimentieren, die ich zuvor noch nicht eingesetzt hatte. Ich arbeitete in einer einfachen, kontrollierten Umgebung und probierte viele verschiedene Variationen aus (mehr als hier aufgeführt sind). Und ich muss noch mehr spielen …

Wodurch wurde dies zu einer Übungssitzung? Nun, ich hatte einige Zeit keine Unterbrechung. Ich hatte etwas Einfaches, das ich ausprobieren wollte, und ich habe es oft versucht. Ich habe jedes Mal nach Feedback gesucht, daher konnte ich daran arbeiten, besser zu werden. Es gab keinen Druck: der Code war effektiv zum Wegwerfen. Es hat Spaß gemacht: Ich habe laufend kleine Fortschritte gemacht, die mich motivierten, weiterzumachen. Am Ende wusste ich schließlich mehr als am Anfang.

Letzten Endes lag es an der freien Zeit, die ich hatte, dass ich üben konnte.Wenn ich unter Druck gewesen wäre, etwa durch eine Deadline für die Ablieferung der Blogsuchfunktionalität, dann wäre die vorhandene Leistung akzeptabel gewesen, und die Übung hätte niemals stattgefunden. Aber diese 45 Minuten ohne Druck ließen mir Zeit zum Spielen.

Also meine Herausforderung für den Tag: Sehen Sie, ob Sie 45 bis 60Minuten herausholen können, um mit einem kleinen Codeabschnitt zu spielen. Sie müssen nicht unbedingt auf die Leistung achten, Sie können etwa mit der Struktur spielen, oder der Speichernutzung oder der Schnittstelle. Letzten Endes ist das egal. Experimentieren Sie, erfassen Sie die Ergebnisse, verbessern Sie sich.

Anders gesagt, der Code kata ist ein (relativ) einfaches Problem (es ist begrifflich nicht schwer zu fassen), das einen Rahmen bietet, innerhalb dessen man forschen kann. In unserem speziellen Fall ist das Ziel das Designen. Wir basieren unsere Erkundung auf Thomas' Kata Four: Datenbeschädigung.”

Kata Four: Datenbeschädigung

Der Code kata besteht in diesem Fall aus drei Teilen, die wir in einzelnen Schritten durchgehen, einen nach dem anderen, wobei wir laufend designen und die für uns in C# verfügbaren Achsen berücksichtigen (obwohl andererseits die Lösungen in Visual Plus genauso einfach zu handhaben sind).

Schritt 1

Schritte sieht wie folgt aus:

In weather.dat (http://bit.ly/ksbVPs) finden Sie die täglichen Wetterdaten fürMorristown, N.J., für Juni 2002. Laden Sie die Textdatei herunter, und schreiben Sie dann ein Programm, um die Anzahl der Tage (Spalte Eins) mit der kleinsten Temperaturschwankung auszugeben (die Höchsttemperatur ist die zweite Spalte, die Tiefsttemperatur die dritte Spalte).

Die Datei weather.dat sieht so aus, wie in Abbildung 1 dargestellt (außer, das sie sich über 30 Tage erstreckt).

Abbildung 1 Die Textdatei Weather.dat

MMU Juni 2002                                
Dy MxT MnT AvT HDDay AvDP 1HrP TPcpn WxType PDir AvSp Dir MxS SkyC MxR MnR AvSLP
1 88 59 74   53.8   0.00 F 280 9.6 270 17 1.6 93 23 1004.5
2 79 63 71   46.5   0.00   330 8.7 340 23 3.3 70 28 1004.5
3 77 55 66   39.6   0.00   350 5.0 350 9 2.8 59 24 1016.8
4 77 59 68   51.1   0.00   110 9.1 130 12 8.6 62 40 1021.1
. ..                              
28 84 68 76   65.6   0.00 RTFH 280 7.6 340 16 7.0 100 51 1011.0
29 88 66 77   59.7   0.00   040 5.4 020 9 5.3 84 33 1020.6
30 90 45 68   63.6   0.00 H 240 6.0 220 17 4.8 200 41 1022.7
mo 82.9 60.5 71.7 16 58.8   0.00     6.9     5.3      

 

Es ist sofort klar, dass die Datei nicht durch Kommas, sondern durch Positionen getrennt ist – die Spalte “MxT” (max temp) beginnt immer an derselben Stelle, und die Spalte "MnT" (min temp) beginnt an einer anderen festen Stelle. Ein Blick in die Datei in Visual Studio zeigt, dass jede Zeile genau 90 Zeichen umfasst, das Analysieren dieser Datei nach einem Zeile-für-Zeile, Zeichenfolge-für-Zeichenfolge-Arrangement ist trivial, da wir nach Zeilenvorschub oder Längen von 90 Zeichen trennen können.

Danach wird es allerdings unklarer. Da wir in dieser Übung nur die kleinste Temperaturschwankung für den Monat durch Hartcodieren der Positionswerte und Ausführen eines String.Subset auf jeder Zeile ausgeben sollen, würden wir so unser Ziel nicht erreichen. Wir wollen daher einen Schritt weiter gehen und das Problem so verfeinern, dass auch die Fähigkeit erfordert wird, jedes Datenelement für jeden Tag des Monats zu überprüfen.

Erinnern Sie sich daran, dass der Kern des multiparadigmatischen Designs darin liegt, die Gemeinsamkeits-/Variabilitätsachse zu identifizieren, und bei diesem Problem ist bis jetzt die Gemeinsamkeits-/Variabilitätsachse ziemlich unintuitiv – obwohl es leicht zu sehen ist, was wir brauchen, um eine Textdatei zu analysieren und die Ergebnisse zu überprüfen. Die Daten sind im Wesentlichen tabellarischer Art, und sie können je nach den Paradigmen, die wir untersucht haben, auf verschiedene Arten betrachtet werden.

Im Hinblick auf das Vorgehen ist die Datenstruktur die Definition für jede Zeile, und eine objektorientierte Lösung bietet uns nicht viel mehr. Es ist ziemlich einfach, die prozedurale Datenstruktur zu nehmen und die Methoden anzuwenden, um die Daten in der Klasse zu analysieren. Im Wesentlichen sind wir wieder bei "smarten Daten", was funktioniert, obwohl es nicht sehr objektbezogen ist. Für den Augenblick.

Noch weist hier nichts auf den praktischen Nutzen der Metaprogrammiertaktik oder des dynamischen Programmierens hin, außer vielleicht, dass die Datenstruktur eine Art Suche nach dem Spaltennamen ermöglicht, sodass day1[“MxT”] “88” zurückgeben würde. Das funktionale Verfahren könnte interessant sein, da das Analysieren als eine Ansammlung von Funktionen gesehen werden kann, die nacheinander ausgeführt werden, Input aufnehmen und Zeichenfolgen (oder andere analysierte Daten) sowie weitere Zeichenfolgen zum Analysieren der restlichen Datei zurückgeben. Eine solche Technik ist untern dem Namen “Parser Combinators” bekannt, und eine Darstellung würde weit über den Rahmen dieses Artikels hinausgehen.

Keines dieser Verfahren scheint sehr hilfreich zu sein; bis jetzt scheint die beste Lösung ein prozedurales Verfahren zu sein, etwa so wie in Abbildung 2 gezeigt.

Abbildung 2 Durchführung eines prozeduralen Verfahrens

namespace DataMunger
{
  public struct WeatherData
  {
    public int Day;
    public float MxT;
    public float MnT;
    // More columns go here
  }
  class Program
  {
    static void Main(string[] args)
    {
      TextReader reader = new StreamReader("weather.dat");
           
      // Read past first four lines
      reader.ReadLine();
      reader.ReadLine();
      reader.ReadLine();
      reader.ReadLine();
 
      // Start reading data
      List<WeatherData> weatherInfo = new List<WeatherData>();
      while (reader.Peek() > 0)
      {
        string line = reader.ReadLine();
 
        // Guard against "mo" summation line
        if (line.Substring(0, 4) == "  mo")
          continue;
 
        WeatherData wd = new WeatherData();
        wd.Day = Int32.Parse(line.Substring(0, 4).Replace("*", " "));
        wd.MxT = Single.Parse(line.Substring(5, 6).Replace("*", " "));
        wd.MnT = Single.Parse(line.Substring(12, 6).Replace("*", " "));
        // More parsing goes here
 
        weatherInfo.Add(wd);
      }
 
      Console.WriteLine("Max spread: " +
        weatherInfo.Select((wd) => wd.MxT - wd.MnT).Max());
    }
  }
}

Beachten Sie, dass dieser Code bereits ein Problem darstellt; wenn die Analyse bei Tag 9 ankommt, erscheint ein Sternchen in der MnT-Spalte, um anzuzeigen, dass dies der “Tiefpunkt” für den Monat ist, so wie Tag 26 der “Höhepunkt” für den Monat ist. Dies ist lösbar durch Entfernen des “*” aus der Zeichenfolge, aber es ist festzustellen: Die prozedurale Achse ist darauf zentriert, die Datenstruktur zu erstellen und sie zu bearbeiten – in diesem Fall, sie zu analysieren.

Beachten Sie auch die Verwendung von <> hier; bloß weil wir ein prozedurales Verfahren zum Analysieren der Datei verwenden, können wir noch nicht nützliche Klassen anderswo in der Basisklassenbibliothek nutzen. Dadurch wird es trivial, die kleinste Temperaturschwankung herauszufinden – eine einzige LINQ-to-Objects-Abfrage ergibt das gewünschte Ergebnis. (Wir sollten natürlich herausfinden, an welchem Tag diese Schwankung auftritt, um der Aufgabe gerecht zu werden, aber dafür muss man einfach zurückgehen und Max()ing auf etwas anderes als einen Rohfloat anwenden; betrachten Sie dies als Übung für den Leser.

Schritt 2

Wir könnten viel Zeit damit verbringen, herauszufinden, wie wir hierfür einen "wiederverwendbaren" Code schreiben können, aber das wäre so etwas wie die Zukunft vorherzusagen. Dieser Code funktioniert, daher wollen wir zum nächsten Schritt im Kata übergehen:

Die Datei football.dat (http://bit.ly/lyNLya) enthält die Ergebnisse derenglischen Premier League für 2001/2002. Die Spalten "F" und "A" enthalten die Gesamtzahl der Tore, die für und gegen jede Mannschaft in dieser Saison gewertet wurden (Arsenal erzielte 79 Tore gegen seine Gegner und musste 36 Tore hinnehmen). Schreiben Sie ein Programm, um den Namen der Mannschaft mit der geringsten Differenz zwischen "für" und "gegen"-Tore auszudrucken.

Weiter Textanalyse Freuen Sie sich. Die Datei football.dat ist dargestellt in Abbildung 3; sie ist in vieler Hinsicht ähnlich wie weather.dat (Abbildung 1), aber verschieden genug, um einen anderen Analysecode zu verdienen.

Abbildung 3 Die Textdatei Football.dat

  Team P D L D F   A Pts
1. Arsenal 38 26 9 3 79 - 36 87
2. Liverpool 38 24 8 6 67 - 30 80
3. Manchester_U 38 24 5 9 87 - 45 77
4. Newcastle 38 21 8 9 74 - 52 71
5. Leeds 38 18 12 8 53 - 37 66
6. Chelsea 38 17 13 8 66 - 38 64
7. West_Ham 38 15 8 15 48 - 57 53
8. Aston_Villa 38 12 14 12 46 - 47 50
9. Tottenham 38 14 8 16 49 - 53 50
10. Blackburn 38 12 10 16 55 - 51 46
11. Southampton 38 12 9 17 46 - 54 45
12. Middlesbrough 38 12 9 17 35 - 47 45
13. Fulham 38 10 24 14 36 - 44 44
14. Charlton 38 10 14 14 38 - 49 44
15. Everton 38 11 10 17 45 - 57 43
16. Bolton 38 9 13 16 44 - 62 40
17. Sunderland 38 10 10 18 29 - 51 40
18. Ipswich 38 9 9 20 41 - 64 36
19. Derby 38 8 6 24 33 - 63 30
20. Leicester 38 5 13 20 30 - 64 28

 

Wenn wir diese beiden Programme unabhängig voneinander betrachten, ist es leicht zu sehen, dass beide sich auf ziemlich ähnlich Weise auflösen – es wäre ziemlich sinnlos, die Übung nochmals für Fußball durchzugehen.

Schritt 3

Der letzte Schritt von kata führt und jedoch zum Nutzen der Übung.

Nehmen Sie die beiden zuvor geschriebenen Programme und klammern Sie so viele gemeinsamen Code wie möglich aus, sodass Sie zwei kleinere Programme und eine Art gemeinsamer Funktionalität haben.

Dies ist faszinierend, und wirkt sich direkt auf die Gemeinsamkeits-/Variabilitätsanalyse aus.

Gemeinsamkeit/Variabilität

Da wir jetzt über mehr als nur ein Problem zum Analysieren verfügen, also eine Familie von Problemen, wird es einfacher, das Gemeinsame und das Variable zwischen den beiden Problemen herauszufiltern. Diese Analyse, beginnend mit der Analyse der Textdateien, zeigt, dass die Übung im Wesentlichen auf zwei Schritte hinausläuft: das Analysieren der Datei in eine Liste von Rohdaten und dann das Untersuchen dieser Daten mittels einer Art Kalkulation oder Analyse.

Beim Analysieren der Textdateien sind einige Probleme zu berücksichtigen:

  • Beide Dateiformate haben eine "Kopfzeile", die ignoriert werden muss.
  • Beide Formate sind positionsbasiert.
  • Beide Datenformaten haben Zeilen, die ignoriert werden müssen (die “mo”-Summierungszeile in wheather.dat, der visuelle Marker “------” in football.dat).
  • Weather.dat enthält einige leere Spalten; football.dat nicht.
  • Beide Dateiformate unterstützen im Prinzip numerische und Zeichenfolgenspalten (außer das weather.dat auch “*” Werte enthält, die irgendwie erfasst werden müssen).

Das Kalkulieren der Ergebnisse ist sehr davon abhängig, wie die analysierten Daten enden, wir sollten also dort beginnen. Wir haben mehrere Methoden, basierend auf jedem Paradigma, mit denen wir beginnen können:

Prozedural Diese Achse ist konzentriert sich auf das Erfassen von Gemeinsamkeiten in Datenstrukturen. Bei zwei verschiedenen Dateiformaten wollen wir eindeutig hier die Variabilität erfassen, daher ist prozedural aussichtsreich. Es wäre möglich, eine Datenstruktur zu erstellen, die beide Dateiformate erfasst, aber das ist wahrscheinlich ungeschickt im Vergleich zu den anderen Paradigmen.

Objektorientiert Die Gemeinsamkeit zwischen zwei Dateien legt die Verwendung einer abstrakten Klase “TextParser” nahe, um grundlegende Analysefunktionen bereitzustellen, einschließlich der Fähigkeit, Zeilen auszulassen. Variabilität entsteht beim Analysieren der einzelnen Zeilen; das bedeutet, das Unterklassen Vorqang vor einer Art "ParseLine"-Methode haben müssen, um die eigentliche Zeile-für-Zeile-Analyse durchzuführen. Wie die analysierten Werte aus dem TextParser-Subtyp abgerufen werden, um den min/max-Vergleich durchzuführen, kann jedoch problematisch werden, da die Spaltentypen ebenfalls variieren. Historisch hat das Microsoft .NET Framework dies (bei SQL-Datensätzen) durch Zurückgeben von Objekten gelöst, was wir nötigenfalls tun könnten. Dadurch werden jedoch potentielle Typsicherheitsfehler eingeführt, da Objekte umgewandelt werden müssten, um verwendbar zu sein, und das könnte gefährlich sein.

Meta Mehrere unterschiedliche Lösungen bieten sich im Meta-Objekt-/Meta-Programmbereich an. Das attributive Verfahren legt nahe, dass die Klasse TextParser einen "Record"-Typ annehmen sollte, in dem jede beschriebene Spalte ein benutzerdefiniertes Attribut Start/Länge hat, das beschreibt, wie die Zeilen analysiert werden, etwa so:

public struct WeatherData
{
  [Parse(0, 4)]
  public int Day;
  [Parse(5, 6)]
  public float MxT;
  [Parse(12, 6)]
  public float MnT;
}

Der TextParser könnte dann parametrisiert werden, um der Record-Typ anzunehmen (TextParser<RecordT>) und die benutzerdefinierten Attributes in der Laufzeit verwenden, um herauszufinden, wie jede Zeile analysiert werden soll. Die s würde dann eine Liste von Aufzeichnungen (List<RecordT>) zurückgeben, aus der wir die zuvor erwähnten Kalkulationen durchführen könnten.

Alternativ legt das generative Programmieren nahe, dass eine Quellformat irgendeiner Art die Textdatei beschreibt, und der Parser für jede Art von Datei auf der Basis dieses Quellformats generiert wird.

Dynamisch Die Wahl eines dynamischen Verfahrens ist etwas seltsam, da es für .NET ein neues Verfahren ist, aber hier könnten wir uns vorstellen, dass eine TextParser-Klasse eine Zeichenfolge nimmt, die beschreibt, wie jede Datei zu analysieren ist. Das wäre fast eine kleine Programmiersprache für sich, die vielleicht reguläre Ausdrücke enthielte oder (in unserem Fall) nur Positionsdaten verwenden würde, da das alles ist, was für dieses Problem erforderlich ist.

string parseCommands =
  "Ignore; Ignore; Ignore; Ignore; Repeat(Day:0-4, MxT:5-6, MnT:12-6)";
TextParser parser = new TextParser(parseCommands);
List<string> MxTData = parser["MxT"];
List<string> MnTData = parser["MnT"];

Dies eindeutig verschieden von dem Meta-Verfahren, da hier die Typsicherheit fehlt, die das Meta-Verfahren bieten könnte. Ein Meta-Verfahren erfordert jedoch Komplierzeitänderungen, wenn sich das Dateiformat ändert, während ein dynamisches Verfahren auf Grundlage von namenbasierter Variablität arbeitet, die mit den Änderungen mitgehen könnte. Das dynamische Verfahren bietet mehr Flexibilität, wobei aber die interne Komplexität zunimmt.

Das vom generativen Meta-Verfahren verwendete Quellformat könnte das sein, was in der Laufzeit verarbeitet wird, wobei der Parser in der Laufzeit erstellt wird und nicht in der Quellzeit.

Funktional In mancher Hinsicht ist das funktionale Verfahren das seltsamste, da es nahelegt, dass die Variabilität im Algorithmus – im Analysieren liegt, und daher die TextParser-Klasse mehr Funktionen annehmen sollte, die bescheiben, wie der Text analysiert wird, zeilenweise oder spaltenweise oder beides. Zwie Dinge, die der TextParser können muss, sind z. B. das Ignorieren nicht-analysierbarer Zeilen und das Zerlegen einer Zeile in Konstituenten. Diese sollten als Funktionsinstanzen auf dem TextParser selbst eingerichtet werden, und entweder durch einen Konstruktor eingeführt oder über Eigenschaften eingestellt werden, wie in Abbildung 4 gezeigt.

Abbildung 4 Ein funktionaler Ansatz.

TextParser<WeatherData> parser = new TextParser<WeatherData>();
parser.LineParseVerifier =
  (line) =>
  {
    if ( (line.Trim().Length == 0) || // Empty line
         (line.Contains("MMU")) ||    // First header line
         (line.Contains("Dy")) ||     // Second header line
         (line.Contains("mo")))
        return false;
    else
      return true;
  };
parser.ColumnExtracter =
  (line) =>
  {
    WeatherData wd = new WeatherData();
    wd.Day = line.Substring(0, 4);
    wd.MxT = line.Substring(5, 6);
    wd.MnT = line.Substring(12, 6);
    return wd;
  };
List<WeatherData> results = parser.Parse("weather.dat");

TextParser verwendet den parametrisierten Typ nur, um den WeatherData-Typ für größere Typsicherheit zu erfassen; er könnte so geschrieben werden, dass er nur ein generisches System.Object zurückgibt, wenn das gewünscht oder einfacher ist.

Zusammenfassung

Offensichtlich gibt es nicht nur einen einzigen Zugang zu dem Problem – sobald andere Erfordernisse betrachtet werden, können wir besser sehen, wo die Variabilität liegt, und erhalten daher ein besseres Gefühl für die Gemeinsamkeiten, die erfasst werden sollen. Dies hebt nebenbei die Wichtigkeit des Umbenennens hervor: Da wir die Zukunft nicht vorhersagen können, bedeutet das Umbenennen von Code, dass wir uns zwar mit unserer Kommunalitätsvariierbarkeitsanalyse irren können, dass wir sie aber deshalb nicht gleich wegwerfen und neu beginnen müssen, wenn diese Fehler zutage treten.

Multiparadigmatische Design ist kein einfach zu verstehendes Thema, besonders in nur einer Sitzung. Es waren 10 Artikel nötig, um es zu beschreiben, und es ist wohl zu erwarten, dass es viel länger dauern wird, bis Sie es in Ihr eigenes Denken übernommen haben. Aber dadurch können Sie mit der Zeit zu wesentlich flexibleren und bequemeren Designs kommen und sogar Lösungen für knifflige Probleme anbieten, die andere Entwickler neidisch machen, wenn sie sich fragen, wie Sie die Lösung im Nebel der Probleme finden konnten. Denken Sie schließlich daran, dass das multiparadigmatische Verfahren mit der Gemeinsamkeit und Variabilität beginnt und endet – seien Sie sich dessen bewusst, und Vieles klärt sich von selbst.

Zum Schluss möchte ich dringend empfehlen, Data Munging kata zu nehmen und entschieden zu versuchen, jede der zwölf Analyseübungen zu lösen und dabei jedes der fünf verschiedenen Paradigmen einzeln anzuwenden, und dann nach einem Weg zu suchen, sie zu kombinieren, um ein leistungsfähiges, wiederverwendbares Tools zu erstellen. Was passiert, wen objektorientiert mit funktional oder dynamisch kombiniert wird? Wird die Lösung einfacher oder komplizierter? Nehmen Sie dann das Verfahren und legen Sie ein anderes Dateiformat darauf – wie verhält sich ein CSV-Dateiformat dabei? Noch wichtiger: tun Sie dies in leeren Augenblicken zwischen Jobs und Geschäftsmeetings; die Erfahrung, die Sie dadurch gewinnen, wird sich reichlich auszahlen, wenn Sie versuchen, diese Art von Design unter dem Damoklesschwert einer echten Deadline durchzuführen.

Wie schon gesagt, aber der Wiederholung wert: Multiparadigmatische Sprachen sind da, in allgemeiner Verwendung, und es scheint, das sie bleiben werden. Die verschiedenen Visual Studio 2010-Sprachen haben alle einen gewissen Anteil dieser Paradigmen; C++ hat z. B. einige parametrische Metaprogrammierfunktionen, die im verwalteten Code nicht möglich sind, aufgrund er Art, wie der C++-Compiler arbeitet; und gerade erst (im neuesten C++0x-Standard) sind Lambda-Ausdrücke hinzugekommen. Selbst die viel gescholtenen ECMAScript/JavaScript/Jscript-Sprachen können Objekte, Prozeduren, Metaprogrammierung und dynamische und funktionale Paradigmen erstellen; in der Tat basiert viel von JQuery auf diesen Ideen. Je eher diese Ideen in Ihrem Gehirn Wurzeln schlagen, desto eher werden Sie in der Lage sein, sich einen Weg durch die schwierigsten Situationen zu kodieren.

Viel Spaß beim Programmieren!

Ted Neward ist ein Geschäftsführer von Neward & Associates, einer unabhängigen Firma, die sich auf .NET Framework- und Java-Plattformsysteme für Unternehmen spezialisiert hat. Er hat mehr als 100 Artikel geschrieben, ist ein C#-MVP und ein INETA-Sprecher und hat mehrere Bücher allein und in Zusammenarbeit mit anderen geschrieben, darunter „Professional F# 2.0“ (Wrox 2010). Er berät und hilft regelmäßig – Sie können ihn unter erreichen, wenn Sie möchten, dass er in Ihrem Team mitarbeitet, oder lesen Sie seinen Blog unter http://blogs.tedneward.com.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Anthony D. Green