Zum Inhalt springen

Verständnisfrage Abstract Factory Pattern


Empfohlene Beiträge

Geschrieben

Hallo,

ich habe mal angefangen mir die Videos aus #6 (Danke nochmal!) anzuschauen.

Dort wird (wie an vielen anderen Stellen auch) das abstract factory pattern mit einer Datenbankverbindung mittels der DBConnection aus dem .NET-Framework erklärt.

... die abstrakte factory soll nicht wissen, welches Objeckt sie eigentlich erzeugt.

Okay..

Aber... Irgendwo in der .NET-Implementierung der Basisklasse muss dann doch die Unterscheidung stattfinden, anhand der entschieden wird, welche der möglichen Implementierungen nun stattfinden soll? Oder stehe ich da gerade total auf dem Schlauch?

Geschrieben

Leider kenne ich mich nicht mit .NET aus. Ich kann aber allgemein was dazu sagen.

Das Factory pattern dient dazu ein Obejekt zu erzeugen über einen Methoden aufruf und nicht wie überlich über den Konstruktor. Man könnte sagen ähnlich eines Lazy autoloads.

In dem Fall ist es der Factory doch egal welches Objekt erzeugt wird.

Beispiel:


class Factory {

static public function get( $class_name, $params = null ) 

{ 

require_once $class_name.'.class.php'; 

return new $class_name( $params ); 

} 

}

$test = Factory::get( 'MeineKlasse' );



Geschrieben (bearbeitet)

Ich hab dir mal ein Sample für ne Class Factory gebaut.

der Aufruf geht über


var rule = ClassFactory<IUser>.CreateInstance();

IUser ist ein Interface in einem Projekt, User ist eine konkrete IUser Implementierung die wir zurückgeben möchten. In der App Config stehen dann die Full Type Names von IUser und User:

<appSettings>

    <add 

      key = "Contracts.IUser" 

      value ="Logic.User, User"

      />

  </appSettings>

So erreicht man lose Kopplung und du kannst zu deinem projekt eine neue User Implementierung hinzufügen und über dein XML File ranstecken, ohne dein ganzes Projekt neu kompilieren zu müssen. Du kannst einfach die DLL ersetzen. Die Konfiguration steuert die app.config, das ganze nennt sich das Inversion of Control ;-)

public static class ClassFactory<T>

        where T : class

    {

        private static readonly string TypeFullName = typeof(T).FullName;


        private static string GetTypeNameFromConfig()

        {

            var typeName = ConfigurationManager.AppSettings[TypeFullName];

            if (string.IsNullOrEmpty(typeName))

            {

                throw new ConfigurationErrorsException(

                    string.Concat(

                        "Configuration setting not found: ", 

                        TypeFullName

                        )

                    );

            }

            return typeName;

        }


        public static T CreateInstance()

        {

            var settingName = GetTypeNameFromConfig();

            return CreateInstanceByName(settingName);

        }


        public static T CreateInstanceByName(string name)

        {

            if (string.IsNullOrEmpty(name))

            {

                throw new ArgumentNullException("name");

            }

            var type = Type.GetType(name);

            if (type == null)

            {

                throw new TypeLoadException(

                    string.Concat("Type not found: ",name)

                    );

            }

            var instance = Activator.CreateInstance(type) as T;

            if (instance == null)

            {

                throw new TypeLoadException(

                    string.Concat("Type does not implement ", TypeFullName)

                    );

            }

            return instance;

        }

    }

Bearbeitet von SilentDemise
Geschrieben
Wozu brauchst du das denn?

Wissen wollen.

Das sollte eher zu Softwaretechnik gehören

macht ja nix.

ist ein Entwurfsmuster.

Jup... deswegen auch die Frage nach abstract factory pattern ;)

Geschrieben

Nochmal zur Klärung:

a) Factorypattern kommt zum Einsatz bei der Objektgeneration

B) Abstract Factory dient dazu Factories zu bauen

... die abstrakte factory soll nicht wissen, welches Objeckt sie eigentlich erzeugt.

Vollkommen korrekt (siehe b).

Missverständlich ist in dem Zusammenhang lediglich die Bezeichnung "Objekt". Natürlich weiß die abstract factory, dass sie factories erzeugt (Ihre Objekte), aber Sie weiß nichts von den Objekten der Factory.

Im Beispiel geht es um die DbProviderFactories.GetFactory-Methode.

Es gibt unterschiedliche Arten von Datenbankanbindungen:

* System.Data.Odbc.OdbcFactory

* System.Data.OleDb.OleDbFactory

* System.Data.OracleClient.OracleClientFactory

* System.Data.SqlClient.SqlClientFactory

Und zu jeder Anbindung gibt es eine entsprechende Factory.

Die Methode DbProviderFactories.GetFactory-Methode liefert Dir ein Factory-Objekt zurück, welches die Methode CreateConnection() unterstützt.

Das bedeutet für Deinen Code, dass Du von allem unabhängig bist.

Du sagst quasi: ich benötige irgendeine Verbindung zu irgendeiner Datenbank und fertig!

Die DbProviderFactories-Klasse weiß selbst nichts von den konkreten Datenbankanbindungen.

DbProviderFactories liefert eine DbProviderFactory zurück, die letztlich Deine Anbindung erledigt.

Hier ein Beispiel für eine abstract Pizza factory:


class AbstractPizzaFactory
{
private static Dictionary<object, Func<IPizzaFactory>> factories;

public static IPizzaFactory GetPizzaFacotryForType<T>()
{
Func<IPizzaFactory> factoryMethod;

if (factories.ContainsKey(typeof(T)))
{
factoryMethod = factories[typeof (T)];
}
else throw new ApplicationException(string.Format("Factory {0} not registered", typeof(T)));
return factoryMethod();
}

static AbstractPizzaFactory()
{
factories=new Dictionary<object, Func<IPizzaFactory>>();
RegisterFactories();
}

static void RegisterFactories()
{
factories.Add(typeof(PizzaTonno),(()=>new PizzaTonnoFactory));
factories.Add(typeof(PizzaQuadroStaggioni), (()=> new PizzaQuadroStaggioniFactory));
}
}
[/php]

Wenn ich eine Factory für PizzaTonno benötige, frage ich einfach bei der abstract factory nach.

Geschrieben
Und zu jeder Anbindung gibt es eine entsprechende Factory.

Die Methode DbProviderFactories.GetFactory-Methode liefert Dir ein Factory-Objekt zurück

Ah jetzt ja.... das war der Punkt, der irgendwie gefehlt hat...

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...