.NET Blog   ·   .NET Casts   ·   .NET GUI Foren   ·   .NET BlogBook   ·   WPF Blogger   ·   visual studio one   ·   ASP.NET professional

  • ACHTUNG - NEUES BLOG

    Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
Download .NET Essentials Installer
Trickkiste

UML Modellierung mit Visual Studio

03.10.07 - Entwicklung, Patterns, .NET, Visual Studio
Beitrag von Norbert Eder
 Wer auf der Suche nach einem UML Modelling-Tool für Visual Studio ist, dem sei eine weitere Variante durch tangible engineering geboten. Zusätzlich zum kostenpflichtigen Tool tangible architect 4.0 gibt es auch eine kostenlose Variante die folgende Diagramme unterstützt:
  • Case Diagrams
  • Component Diagrams
  • State Charts
  • Class Diagrams
  • Activity Diagrams
  • Persistent Object Models

Hier ein Screenshot:

Die erstellten Diagramme und Modelle sind mit der kostenpflichtigen Variante kompatibel.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Enterprise Library Contrib September 2007 verfügbar

02.10.07 - Entwicklung, Patterns, .NET, Allerlei
Beitrag von Norbert Eder
 Seit gestern ist die Enterprise Library Contrib September 2007 auf CodePlex verfügbar. Was genau ist die EntLib Contrib?

"EntLib Contrib is a community-developed library of extensions to the patterns & practices Enterprise Library."

Folgende Features sind enthalten:
  • Erweiterungen Data Access Application Block: Provider für MySql, SqLite und SqlEx
  • Erweiterungen Exception Handling Application Block: SqlException Wrap Handler
  • Erweiterungen Logging Application Block: LogParser
  • Erweiterungen Policy Injection Application Block: PostSharp4EntLib, neue Matching-Regeln und neue Call-Handler
  • Erweiterungen Validation Application Block: CollectionCountValidator, TypeValidator, ObjectValidator usw.


  1 Kommentar - 617 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Enterprise Library für Visual Studio 2008 geplant

29.08.07 - Entwicklung, Patterns, .NET, Visual Studio, Internet, Community
Beitrag von Norbert Eder
 Grigori Melnik schrieb in seinem Blog, dass das pattern & practices Team eine Version der Enterprise Library für Visual Studio 2008 (Orcas) plant. Dazu wurde eine Umfrage gestartet die 10 Fragen enthält. Dadurch soll in Erfahrung gebracht werden, welche Szenarios und darauf abzielt, zu erfahren, was den einzelnen Entwicklern an der EntLib fehlt.

Wer sich also einbringen möchte, der möge an der Umfrage teilnehmen, um ein möglichst großes Feedback für die Enterprise Library zu leisten, die ja tatsächlich sehr hilfreich für uns Entwickler ist.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


[Enterprise Library] NLog Trace Listener im Eigenbau

19.06.07 - Entwicklung, Patterns, .NET, Grundlagen
Beitrag von Norbert Eder
 Eventuell hat sich der werte Leser die Enterprise Library [1] bereits einmal genauer angesehen. Wenn nicht, dann möchte ich zuerst ein paar einführende Worte loswerden.

Die Enterprise Library besteht aus sogenannten Blocks. Jeder Block besitzt eine eindeutige Aufgabe. Beispielsweise gibt es den Logging und den Exception Handling Block. Der Vorteil besteht darin, dass es mit Hilfe der Blocks das Verhalten über die Konfiguration (App.config, Web.config, ...) gesteuert werden kann. Beispiel:

Bei Exceptions stellt sich die Frage, wie denn diese im Spezialfall zu behandeln sind. Sind sie für den User sichtbar, sollen sie geloggt werden, oder gar der schlimmste Fall: soll sie nicht behandelt werden? Die geworfenen Exceptions werden an den Exception Handling Block übergeben, welcher durch eine Konfigurationsdatei entsprechend eingerichtet wird. Im Nachhinein kann nun festgelegt werden, was mit bestimmten Exceptions passieren soll. Ebenso verhält es sich mit den anderen Blocks.

Beim Logging verhält es sich gleich. Durch die Konfiguration kann festgelegt werden, wohin geloggt werden soll. Hier stehen unterschiedlichste Möglichkeiten bereit: EventLog, Datenbank, Email, Flat File usw. In unserem Beispiel möchten wir allerdings alle geworfenen Exceptions via NLog aufzeichnen.

Sehen wir uns dazu allerdings das Grundgerüst an. Das Beispiel läuft als Konsolenanwendung und Instanziiert eine Klasse DoSomethingClass, welche eine einzige Methode ThrowAnException besitzt:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace ExceptionLoggingDemo
{
    public class DoSomethingClass
    {
        public void ThrowAnException()
        {
            try
            {
                int i = 0;
                i = 1 / i;
            }
            catch (Exception ex)
            {
                ExceptionPolicy.HandleException(ex, "DemoException");
                throw ex;
            }
        }
    }
}

Die Konsolen-Anwendung selbst sieht folgendermaßen aus:
using System;
using System.Collections.Generic;
using System.Text;

namespace ExceptionLoggingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            new DoSomethingClass().ThrowAnException();
            Console.WriteLine("Exception thrown");
            Console.ReadKey();
        }
    }
}

Nun binden wir die Enterprise Library ein bzw. die Teile davon, die wir tatsächlich benötigen. Dabei handelt es sich um folgende Libraries:

- Microsoft.Practices.EnterpriseLibrary.Common
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging
- Microsoft.Practices.EnterpriseLibrary.Logging

Bevor wir nun daran gehen, die Enterprise Library zu konfigurieren, erstellen müssen wir uns genauer ansehen, wie der Ablauf aussehen soll.

Grundsätzlich binden wir den Exception Handling Block ein. Dieser fängt unsere Ausnahmen auf. Hier müssen wir eine neue Exception Policy hinzufügen, damit unsere Exception auch aufgefangen wird (hier sind unterschiedliche Policies möglich und können somit auch unterschiedlich behandelt werden). Dieser Policy hängen wir einen Logging Block um. Hierbei ist schön zu sehen, dass die einzelnen Blocks sehr gut miteinander zusammenarbeiten. Durch diese Definition legen wir fest, dass auftretende Exceptions mitgeloggt werden sollen. Nun muss der Logging Block entsprechend konfiguriert werden. Es muss also angegeben werden, wohin die Daten geschrieben werden und wie diese formatiert werden sollen. Daraus ergeben sich zwei wichtige Bestandteile des Logging Blocks:

- Trace Listener
- Formatter

Der Trace Listener bekommt die zu schreibenden Daten übermittelt. Durch die Einbindung eines Formatters können diese Daten entsprechend formatiert werden, um besser lesbar bzw. einfacher zu verarbeiten sind. Als Formatter stehen ein TextFormatter und ein XmlFormatter zur Verfügung. Eigene Ableitungen sind an dieser Stelle natürlich möglich. Zudem wissen wir nun, an welcher Stelle wir ansetzen müssen: Wir benötigen einen CustomTraceListener.

Dazu wird ein eigenes Projekt erstellt, welches den benutzerdefinierten Listener enthalten wird. Nachfolgend der Sourcecode des Listeners:
[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class NLogTraceListener : CustomTraceListener
{
    private LogLevel _logLevel = LogLevel.Info;

    public override void TraceData(
        TraceEventCache eventCache, 
        string source, 
        TraceEventType eventType, 
        int id, 
        object data)
    {
        if (data is LogEntry && this.Formatter != null)
        {
            switch (eventType)
            {
                case TraceEventType.Critical:
                    _logLevel = LogLevel.Fatal;
                    break;
                case TraceEventType.Error:
                    _logLevel = LogLevel.Error;
                    break;
                case TraceEventType.Information:
                    _logLevel = LogLevel.Info;
                    break;
                case TraceEventType.Warning:
                    _logLevel = LogLevel.Warn;
                    break;
                case TraceEventType.Verbose:
                    _logLevel = LogLevel.Debug;
                    break;
                default:
                    _logLevel = LogLevel.Info;
                    break;
            }

            this.WriteLine(this.Formatter.Format(data as LogEntry));
        }
        else
        {
            this.WriteLine(data.ToString());
        }
    }

    public override void Write(string message)
    {
        LogManager.GetCurrentClassLogger().Log(_logLevel, message);
    }

    public override void WriteLine(string message)
    {
        LogManager.GetCurrentClassLogger().Log(_logLevel, message);
    }
}

Insgesamt werden drei Methoden überschrieben (wobei ansich nur zwei Methoden tatsächlich benötigt werden):

- TraceData
- Write
- WriteLine

Wichtig sind zwei Dinge: Durch das Überschreiben der Methode TraceData kommen wir an den TraceEventType. Dieser gibt an, um welches Fehler-Level es sich handelt (Critical, Error, Warning, Info, ...). Dies benötigen wir, um es an NLog weitergeben zu können. Der Rest besteht ansich im Aufruf der Methode WriteLine unter Einbindung des zugewiesenen Formatters.

Schließlich muss noch eine App.config eingebunden werden. In dieser Konfigurations-Datei wird die Konfiguration der Enterprise-Library hinterlegt. Per rechter Maustaste auf die App.config kann die Enterprise Library Configuration gestartet werden, welche sich mittlerweile netterweise ins Visual Studio integriert. Zur Konfiguration müssen die Einträge für das Exception Handling und für das Logging hinzugefügt werden. Beim Logging verwenden wir unseren CustomTraceListener. Dazu ist eine Assembly anzugeben (unser separates Projekt). Zu beachten ist hier folgendes:



Die Enterprise Library kann sowohl signiert als auch unsigniert eingebundern werden. Wird die signierte Variante verwendet, muss auch die eigene Assembly signiert sein. Zudem muss (im Falle eines TraceListeners) die Klasse von CustomTraceListener abgeleitet sein und folgendes Attribut gesetzt haben:
[ConfigurationElementType(typeof(CustomTraceListenerData))]

Damit ist alles getan, um unseren eigenen TraceListener laden zu können.



Als Verbesserung könnte hier ein eigener Formatter erstellt werden, welcher die Daten in einer besser lesbaren Form in unseren NLogTraceListener schreibt.

Hier nun der Download des Beispiel-Projektes:
Download NLog Trace Listener Demo

[1] Download Enterprise Library 3.1 (May 2007)
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Builder Pattern in C#

01.06.07 - Entwicklung, Patterns, .NET, Grundlagen
Beitrag von Norbert Eder
 Eine Diskussion mit Thomas veranlasste mich, einige Beispiele für ein Builder Pattern im .NET Framework zu suchen, zu beschreiben und selbst ein kleines Beispiel aus der Praxis zu liefern.

Einführung


Grundlegend zählt das Builder Pattern zu den Object Creational Patterns - es werden durch dieses Entwurfmuster also Objekte erstellt. Sinn und Zweck des Builder Patterns ist es, den Objekt-Erstellungsprozess von der Repräsentation des Objektes zu entkoppeln. Dadurch ist es möglich, mit demselben Erstellungsprozess unterschiedliche Repräsentationen erstellen zu können.

Beispiel aus dem .NET Framework


Ein sehr gutes Beispiel aus dem .NET Framework ist durch den DbConnectionStringBuilder geben. Dieser stellt die Basisklasse für stark typisierte Ableitungen dar (SqlConnectionStringBuilder etc.). Sehen wir uns an dieser Stelle einen kurzen Sourcecode an:
SqlConnectionStringBuilder connStringBuilder = 
  new SqlConnectionStringBuilder();
connStringBuilder.DataSource = "(local)";
connStringBuilder.InitialCatalog = "MyDatabase";
connStringBuilder.UserID = "username";
connStringBuilder.Password = "$password%";

SqlConnection sqlConn = 
  new SqlConnection(connStringBuilder.ToString());

Mit Hilfe des SqlConnectionStringBuilder ist es möglich, einfach einen syntaktisch korrekten ConnectionString zu erstellen, woraus in weiterer Folge ein Connection-Objekt gebildet werden kann.

Ein eigenes Beispiel


Nun sehen wir uns anhand eines eigenen Beispiels die Implementierung des Builder Patterns an. Grundlage bilden Adressdaten, die in einer XML-Datei vorliegen und importiert werden müssen. Den Part des Importierens ersparen wir uns. Die erstellten Objekte werden lediglich in eine Liste gelegt und anschließend per ToString ausgegeben.



Wie in der Abbildung zu sehen ist, besteht diese Implementierung des Builder-Patterns aus zwei wichtigen Teilen:

- AddressBuilder
- AddressParser

Der Parser selbst ist kein echter Bestandteil des ursprünglichen Builder-Patterns, wurde jedoch in diesem Beispiel zum Parsen der Adressdaten herangezogen und in das Pattern integriert, um die Zuständigkeiten der Objekte sauber zu trennen.
public class AddressParser : AParser
{
    AddressBuilder _builder = null;

    public AddressParser(IBuilder builder)
    {
        _builder = (AddressBuilder)builder;
    }

    public override void Parse(XmlNode data)
    {
        if (data != null && _builder != null)
        {
            _builder.ResetData();

            XmlNode xnStreet = data.SelectSingleNode("street");
            XmlNode xnStreetNumber = 
                data.SelectSingleNode("streetnumber");
            XmlNode xnZip = data.SelectSingleNode("zip");
            XmlNode xnCity = data.SelectSingleNode("city");
            XmlNode xnCountry = data.SelectSingleNode("country");

            if (xnStreet != null) 
                _builder.Street = xnStreet.InnerText;
            if (xnStreetNumber != null) 
                _builder.StreetNumber = xnStreetNumber.InnerText;
            int zip = 0;
            if (xnZip != null) 
                Int32.TryParse(xnZip.InnerText, out zip);
            _builder.Zip = zip;
            if (xnCity != null) 
                _builder.City = xnCity.InnerText;
            if (xnCountry != null) 
                _builder.Country = xnCountry.InnerText;                
        }
    }
}


Der AddressBuilder selbst besitzt nun die Aufgabe, das eigentliche Address-Objekt zu erstellen und zurück zu liefern.
public class AddressBuilder : ABuilder
{
    private string _street = null;
    private string _streetnumber = null;
    private int _zip = 0;
    private string _city = null;
    private string _country = null;

    public string Street
    {
        get { return this._street; }
        set { this._street = value; }
    }

    public string StreetNumber
    {
        get { return this._streetnumber; }
        set { this._streetnumber = value; }
    }

    public int Zip
    {
        get { return this._zip; }
        set { this._zip = value; }
    }

    public string City
    {
        get { return this._city; }
        set { this._city = value; }
    }

    public string Country
    {
        get { return this._country; }
        set { this._country = value; }
    }

    public void ResetData()
    {
        this._city = null;
        this._country = null;
        this._street = null;
        this._streetnumber = null;
        this._zip = 0;
    }

    public override BaseObject Build()
    {
        Address address = new Address();

        address.City = this._city;
        address.Country = this._country;
        address.Street = this._street;
        address.StreetNumber = this._streetnumber;
        address.Zip = this._zip;

        return address;
    }
}

Die Ausführung der gesamten Anwendung erfolgt durch nachfolgenden Sourcecode:
List<Address> addresses = new List<Address>();

XmlDocument doc = new XmlDocument();
doc.Load("addresslist.xml");

XmlNodeList xnlAddresses = doc.SelectNodes("/addresses/address");

if (xnlAddresses != null && xnlAddresses.Count > 0) 
{
    AddressBuilder builder = new AddressBuilder();
    AddressParser parser = new AddressParser(builder);

    foreach (XmlNode xnAddress in xnlAddresses) 
    {
        parser.Parse(xnAddress);
        Address address = (Address)builder.Build();
        addresses.Add(address);
    }
}

foreach (Address a in addresses)
{
    Console.WriteLine(a.ToString());
    Console.WriteLine("---------------------");
}

Console.Read();


Fazit


Über dieses Pattern können durch kleine Anpassungen unterschiedlichste Typen abgewickelt werden, was sich sehr schnell positiv auswirkt und zudem alle für die passende Aufgabe notwendigen Schritte trennt. Dadurch lassen sich diese entsprechend anpassen bzw. gänzlich ersetzen.

Download Builder Pattern Demo

  2 Kommentare - 716 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Enterprise Library 3.0 - April 2007 erschienen

10.04.07 - Entwicklung, Patterns, .NET, Allerlei
Beitrag von Norbert Eder
 Die Enterprise Library 3.0 - April 2007 ist verfügbar und kann heruntergeladen werden. Folgende Application Blocks sind verfügbar:

- Caching Application Block
- Cryptography Application Block
- Data Access Application Block
- Exception Handling Application Block
- Logging Application Block
- Policy Injection Application Block
- Security Application Block
- Validation Application Block

Weitere Änderungen betreffen unter anderem die Integration der Windows Communication Foundation (WCF).

Download Enterprise Library 3.0 - April 2007

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Proxy-Pattern: Beschreibung und Beispiele

06.04.07 - Entwicklung, Patterns, .NET, Grundlagen
Beitrag von Norbert Eder
 Ein Proxy kann an vielen Stellen eingesetzt werden. Grundlegend handelt es sich dabei um einen Platzhalter für das tatsächlich aufzurufende Objekt. Das heißt, es leitet vom gleichen Interface ab, besitzt die gleichen Methoden, leitet aber alle Anfragen an das dahinterliegende Objekt weiter. Aber welchen Vorteil besitzt dieses Pattern nun?

Durch dieses Pattern ist es möglich, Änderungen und Prüfungen einzuführen, ohne das eigentliche Objekt abändern zu müssen. So können beispielsweise Sicherheitsprüfungen stattfinden (Protection Proxy). Dies bedeutet, dass das Proxy-Objekt zuerst überprüft, ob der Aufrufer über die notwendigen Rechte verfügt, bevor der Aufruf weitergeleitet und abgearbeitet wird. Weiters wird häufig ein Remote Proxy verwendet, der die Anfrage kodiert, an das echte Objekt sendet, die Antwort dekodiert und zurück gibt. Dieser Vorgang ist unter anderem dann interessant, wenn Application Domains erstellt werden sollen, die zur Laufzeit die Möglichkeit bieten sollen, entladen werden zu können. Schließlich wäre da noch Cache Proxies, die bestimmte Daten des eigentlichen Objektes cachen und so diverse Vorgänge beschleunigen können. Das sind jedoch nicht die einzigen Möglichkeiten. So gibt es noch Synchronization Proxies und viele weitere.

Ein einfaches Grundgerüst eines Proxies findet sich nachfolgend:
using System;
using System.Collections.Generic;
using System.Text;

namespace ProxyPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            CalculatorProxy proxy = new CalculatorProxy();
            Console.WriteLine(
                String.Format("12 + 17 = {0}", proxy.Add(12, 17))
                );
            Console.WriteLine(
                String.Format("12 - 17 = {0}", proxy.Sub(12, 17))
                );

            Console.Read();
        }
    }

    public interface ICalculator
    {
        decimal Add(decimal x, decimal y);
        decimal Sub(decimal x, decimal y);
    }

    public class Calculator : ICalculator
    {
        public decimal Add(decimal x, decimal y)
        {
            return x + y;
        }

        public decimal Sub(decimal x, decimal y)
        {
            return x - y;
        }
    }

    public class CalculatorProxy : ICalculator
    {
        private Calculator _calculator = new Calculator();

        public decimal Add(decimal x, decimal y)
        {
            return _calculator.Add(x, y);
        }

        public decimal Sub(decimal x, decimal y)
        {
            return _calculator.Sub(x, y);
        }
    }
}

Dies stellt die einfachste Variante eines Proxies dar. Ein vereinfachter Protection Proxy könnte beispielsweise so aussehen (Erweiterung des obigen Beispiels):
using System;
using System.Collections.Generic;
using System.Text;
using System.Security;

namespace ProxyPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CalculatorProxy proxy = new CalculatorProxy("test2");
                Console.WriteLine(
                    String.Format("12 + 17 = {0}", proxy.Add(12, 17))
                    );
                Console.WriteLine(
                    String.Format("12 - 17 = {0}", proxy.Sub(12, 17))
                    );

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }

    public interface ICalculator
    {
        decimal Add(decimal x, decimal y);
        decimal Sub(decimal x, decimal y);
    }

    public class Calculator : ICalculator
    {
        public decimal Add(decimal x, decimal y)
        {
            return x + y;
        }

        public decimal Sub(decimal x, decimal y)
        {
            return x - y;
        }
    }

    public class CalculatorProxy : ICalculator
    {
        private Calculator _calculator = new Calculator();
        private string _password = "test";
        private string _givenPassword = null;

        public CalculatorProxy(string password)
        {
            this._givenPassword = password;
        }

        public decimal Add(decimal x, decimal y)
        {
            if (this._givenPassword == this._password)
                return _calculator.Add(x, y);
            else
                throw new SecurityException("Not allowed: Add");
        }

        public decimal Sub(decimal x, decimal y)
        {
            if (this._givenPassword == this._password)
                return _calculator.Sub(x, y);
            else
                throw new SecurityException("Not allowed: Sub");
        }
    }
}

Ich möchte nur darauf hinweisen, dass ein Protection Proxy entsprechend abgesichert sein sollte. Die obige Variante dient lediglich der Veranschaulichung und sollte so nicht verwendet werden.

  3 Kommentare - 2928 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Architektur Links

18.02.07 - Entwicklung, Patterns, .NET, Allerlei
Beitrag von Norbert Eder
 Für viele sicherlich interessant sind die Application Blocks von Microsoft. Hierzu gibt es seit einigen Tagen neue Downloads:

Web Client Software Factory — January 2007
Smart Client Offline Application Block

Damit sollte sich der eine oder andere Abend ausfüllen lassen :)

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Enterprise Logging Application Block

23.01.07 - Entwicklung, Patterns, .NET, Grundlagen, Allerlei
Beitrag von Norbert Eder
 Logging muss nicht kompliziert sein. Wer bekannte Logging-Bibliotheken á la NLog nicht verwenden will, oder doch lieber seine Informationen in der Ereignisanzeige sehen möchte, der kann den Enterprise Logging Application Block verwenden.

Mittlerweile findet sich im Paket das Tool Enterprise Library Configuration mit dem Konfigurationen für die unterschiedlichen Application Blocks erstellt werden können. Für mein Beispiel würde dies so aussehen:



Die durch die Konfigurierung entstehende Konfigurations-Datei (welche der .NET Standard Anwendungs-Konfiguration entspricht) musss nun nur mehr in das Anwendungsverzeichnis kopiert werden. Zudem sind folgende Assemblies einzubinden:

Microsoft.Practices.EnterpriseLibrary.Logging


Soll nun ein Eintrag mitgeschrieben werden, erfolgt dies durch den einfachen Aufruf:

Logger.Write("test");


Durch die Möglichkeit, unterschiedliche TraceListener einzusetzen, müssen die Informationen nicht zwangsweise in die Ereignisanzeige geschrieben werden. Auch Datenbanken und andere Ziele sind möglich. Zusätzlich können viele weitere Einstellungen konfiguriert werden.

Download-Link: Enterprise Library 3.0 January 2007 CTP

PS: Man beachte, dass die Enterprise Library zahlreiche weitere Application Blocks inkludiert und somit für jeden Entwickler von Bedeutung sind. Ein Blick darauf lohnt sich also.

  1 Kommentar - 914 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Writing Software Patterns

21.09.06 - Patterns
Beitrag von Norbert Eder
 An dieser Stelle möchte ich auf den Artikel unter [1] von Martin Fowler verweisen, der sich dem Thema Software Patterns widmet. Er beschreibt grundlegend worum es sich bei Software Patterns handelt, warum diese so wichtig sind und beschreibt weiters interessante Themen rund um Patterns.

[1] Martin Fowler - Writing Software Patterns

  Kommentar hinzufügen - 2 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL



Zurück Weiter